2012-03-09 4 views
1

select 문을 실행하는 함수가 있습니다.SQL 유효하지 않은 식별자 오류

Msg 203, Level 16, State 2, Procedure Info_GetWholeNumber, Line 20
The name 'SELECT MAX(LEN(CAST(FLOOR([pcom_audit_cant_con]) AS VARCHAR(38)))) AS WHOLE_NO FROM Auditorias.prod_com_audit' is not a valid identifier.

내가 복사 문을 선택 붙여 넣기가 잘 작동하면 ... 그러므로 그것의 : 내 함수가 다음과 같은 오류와 충돌 변수에 단일 값을 반환하고 설정이 선택 문을 실행하려고 할 때 선택하지 내 EXEC 함께 할 수있는 뭔가가 ... 어쨌든 ... 여기 내 기능 코드의 내가 정말 도움을 주셔서 감사합니다 것이 문제를 해결할 수있는 방법을

ALTER FUNCTION [dbo].[Info_GetWholeNumber] 
(
    @TABLE VARCHAR(MAX) 
    , @COLUMN VARCHAR(MAX) 
) 
RETURNS INT 
AS 
BEGIN 
    -- Declare the return variable here 
    DECLARE @WHOLE_NO INT 

    -- Add the T-SQL statements to compute the return value here 
    DECLARE @SQL VARCHAR(MAX) 
    SET @SQL = 'SELECT MAX(LEN(CAST(FLOOR([' + @COLUMN + ']) AS VARCHAR(38)))) 
     AS WHOLE_NO FROM ' + @TABLE 
    EXEC @WHOLE_NO = @SQL 

    -- Return the result of the function 
    RETURN @WHOLE_NO 

END 

사람이 어떤 아이디어가있는 경우

! 미리 감사드립니다!

업데이트합니다 메신저 진술로 sp_executesql을 기능을 사용하려고 시도하고 난 새로운 기능을 붙여 갈거야, 그래서

확인을 클릭합니다.

메시지 1087, 수준 16, 상태 1, 줄 1 내 의견에 보이는 테이블 변수 "@TBL"

를 선언해야합니다 :

ALTER FUNCTION [dbo].[Info_GetWholeNumber] 
(
@TABLE VARCHAR(MAX) 
, @COLUMN VARCHAR(MAX) 
) 
RETURNS INT 
AS 
BEGIN 
DECLARE @WHOLE_NO INT 
DECLARE @SQL NVARCHAR(MAX) 
DECLARE @PARAMS NVARCHAR(MAX) 

SET @SQL = N'SELECT @WHOLE_NOOUT = MAX(LEN(CAST(FLOOR(@COL) AS VARCHAR(38)))) FROM @TBL' 
SET @PARAMS = N'@COL VARCHAR(MAX), @TBL VARCHAR(MAX), @WHOLE_NOOUT INT OUTPUT' 

EXECUTE sp_executesql @SQL, @PARAMS, @COL = @COLUMN, @TBL = @TABLE, @WHOLE_NOOUT = @WHOLE_NO OUTPUT; 

-- Return the result of the function 
RETURN @WHOLE_NO 

END 

지금이 오류를 얻고있다 변수가 @PARAM 변수 이외의 변수로 선언되지 않았기 때문에 정확합니다 ... 여기에 뭔가 빠졌습니까?

+3

당신은 내가 이후 내 경우에는 select 문 것을 실행에 대한 갈 것이라고 어떻게 기능 – Lamak

+0

@Lamak에'EXEC'을 사용할 수 없습니다 그 동적...? –

+0

여전히 'EXECUTE' 또는'sp_executesql'을 사용할 수 없으며 함수 내에서 다른 저장 프로 시저를 호출 할 수 없습니다. 왜 이것이 기능이되어야합니까? –

답변

4

EXEC 문에서 직접 할당 할 수도없고 동적 범위 내에서d 개의 동적 SQL (직접 범위를 벗어남)에서 변수를 직접 할당 할 수도 없습니다. 이것은 SQL이 함수가 결정적이기를 기대하기 때문에 실제로 함수에서 호출해서는 안됩니다. 실제로는 그렇지 않습니다. (실제로 오류를 수정해도 여전히 작동하지 않습니다.)

이 코드를 어떻게 호출하는지 동적 SQL에서 가치를 얻는 방법을 알아야합니다. 동적 SQL 문자열에서 변수를 전달하려면 출력 매개 변수에 EXEC SP_ExecuteSQL을 사용해야합니다. 여기

간단한 예이다 :이 예에서

DECLARE @whole_no int; 
DECLARE @SQL nvarchar(500); 
DECLARE @Parms nvarchar(500);; 

SET @SQL = N'SELECT @whole_noOUT = 1'; 
SET @Parms = N'@whole_noOUT int OUTPUT'; 

EXECUTE sp_executesql @SQL, @Parms, @[email protected]_no OUTPUT; 
SELECT @WHOLE_NO; 

우리는 PARAM 정의를 설정하고 출력하는 파라미터. 일반적으로 sp_executesql은 동적 SQL 호출에 선호되는 방법입니다. 매개 변수화가 가능하므로 sql을 직접 연결하지 않아도되므로 보안이 강화되지만 SQL을 완전히 매개 변수화 할 때도 계획을 다시 사용할 수 있습니다.

SQL 인젝션 (현재 또는 미래)에 자신을 열어 놓는 것처럼 무의미한 방식으로 동적 SQL을 구축해서는 안된다는 의무적 인 경고를 추가해야합니다. 특정 검색어를 매개 변수화 할 수는 없지만 적어도 []을 하드 코딩하는 대신 열 이름에 QUOTENAME()을 사용해야합니다.

자세한 내용은 여기를 sp_executesql에 읽기 : http://msdn.microsoft.com/en-us/library/ms188001.aspx 그리고 여기에 더에 QUOTENAME() : http://msdn.microsoft.com/en-us/library/ms176114.aspx

+0

방금 ​​내 질문을 업데이트했습니다. 귀하의 제안을 시도했지만 지금은 왜 이런 생각일지도 모르는 또 다른 오류가 있습니까? –

+0

@ Lord-Link 그런 테이블과 열을 매개 변수화 할 수 없습니다. 'sp_executesql'을 호출하기 전에 SQL 문자열을 만들어야 할 필요가있는 것들 :'SET @SQL = N'SELECT @WHOLE_NOOUT = MAX (LAST (CAST (FLOOR ('+ QUOTENAME (@COLUMN) +') AS VARCHAR 38)))) FROM '+ QUOTENAME (@TABLE)'을 호출하고 param 정의에서 제거하십시오. 이렇게하면 출력 변수 만 매개 변수화됩니다. –

+0

글쎄 그게 바로 오류가 발생하지 않는 메신저 이후 뭔가를 한 것 같다 ... 내 쿼리가 붙어 있지만 병이 하나 밖으로 확인하고 내가 왜 찾을 수 있는지 ... 도와 줘서 고마워, 미안 해요 지각 반응 나는 직장에서 끝내고 있었다. 그리고 여기에서 단지 금요일에 monday! :) –

0

Lamak이 맞습니다. 함수 내에서 저장 프로 시저 (또는 업데이트, 삽입, 삭제가 가능한 것)를 실행할 수 없습니다.

함수는 읽기 전용입니다.

함수 대신 저장 프로 시저를 사용하는 것이 좋습니다.

관련 문제