2016-11-29 1 views
0

계층 구조 포럼 사용자가 더 높으면이 문제와 관련된 새로운 질문으로 내 문제를 제안하십시오 : declare variable for query string.쿼리 문자열에 대한 변수

변수를 사용할 수 있기 때문에 여기에서 동적 쿼리를 사용하고 있습니다 (매개 변수 스니핑과 관련된 실험을 위해 필요함). 내 쿼리는 다음과 같습니다 나는 @Sql에 변수 @i의 선언을 이동

'Msg 137, Level 15, State 2, Line 28 
Must declare the scalar variable "@i".' 

다음은 그렇다고 작동합니다

DECLARE @i NVARCHAR(10) 
SET @i = 'POL' 

DECLARE @sql VARCHAR(MAX) 
SET @sql = 'SELECT 

a.something1, 
b.something2, 
c.something3 

FROM 
aaa a WITH(NOLOCK) 
LEFT JOIN bbb b WITH(NOLOCK) ON.... 
LEFT JOIN ccc c WITH(NOLOCK) ON.... 

WHERE 
a.somethingelse = ''aa'' 
AND 
((a.entirelysomethingelse=''aaa'') OR (a.entirelysomethingelse=''aaaa'')) 
AND 
b.anotherdifferentsomething != 41 
AND 
c.yetanotherdifferentthing LIKE(''%@%'') 
AND 
c.datafromvariablewannabe = (@i) 
GROUP BY 
... 
ORDER BY 
...' 
EXECUTE (@SQL) 

내가 좋아하는 내 쿼리 임 점점 오류를 실행하고자합니다. 아직도 나는 그것이 내가 원했던 것이라고 생각하지 않는다. 내가 뭔가 잘못하고 있거나 같이하는 건가요 것은 임 MSG137 오류가 있으므로

DECLARE @sql VARCHAR(MAX) 
SET @sql = ' 

DECLARE @i NVARCHAR(10) 
SET @i = 'POL' 

SELECT 

a.something1, 
b.something2, 
c.something3 

FROM 
aaa a WITH(NOLOCK) 
LEFT JOIN bbb b WITH(NOLOCK) ON.... 
LEFT JOIN ccc c WITH(NOLOCK) ON.... 

WHERE 
a.somethingelse = ''aa'' 
AND 
((a.entirelysomethingelse=''aaa'') OR (a.entirelysomethingelse=''aaaa'')) 
AND 
b.anotherdifferentsomething != 41 
AND 
c.yetanotherdifferentthing LIKE(''%@%'') 
AND 
c.datafromvariablewannabe = (@i) 
GROUP BY 
... 
ORDER BY 
...' 
EXECUTE (@SQL) 

내 코드에서 실수가가 있나요? 아니면 내가 여기서하고 싶은 단지 불가능한 작업이다.

이 쿼리에서 저장 프로 시저를 만들고 싶지 않습니다. 저장 프로 시저에 의존하지 않고 변수를 사용할 수 있기를 원합니다.

하이퍼 링크 된 질문에서 내 이전 질문과 관련된 문제에 대해 관리자/포럼 사용자에게 사과드립니다.

+0

이것은 무엇을 의미합니까? @sql에 변수 @i 선언을 옮기면 작동합니다. 아직도 나는 그것이 무엇을 원하는지 생각하지 않는다 ' – TheGameiswar

+2

변수는 배치에 범위가 지정되고 exec는 별도의 배치에서 실행되므로 동일한 @sql에 포함해야합니다. – TheGameiswar

+0

나는 결과가 좋지만 결과를 얻는 방법이 있다는 것을 의미했습니다. 제가 찾고 있던 것이 아니 었습니다. 나는 내 변수가 "로드 될 수 있도록"쿼리 문자열 (@mortb sugessted와 같이)을 "끊어야"한다는 것을 몰랐다. 거기에. – M3How

답변

2

문자열을 "끊어야"합니다. @i 값은 문자열이 실행되는 범위에서 사용할 수 없으므로 문자열의 일부로 사용해야합니다. 과 같이 : @variable 그렇게 보일 것이다 최적화와

DECLARE @tmp NVARCHAR(10) 
SET @tmp = 'POL' 

DECLARE @sql VARCHAR(MAX) 
SET @sql = 'SELECT 

a.something1, 
b.something2, 
c.something3 

FROM 
aaa a WITH(NOLOCK) 
LEFT JOIN bbb b WITH(NOLOCK) ON.... 
LEFT JOIN ccc c WITH(NOLOCK) ON.... 

WHERE 
a.somethingelse = ''aa'' 
AND 
((a.entirelysomethingelse=''aaa'') OR (a.entirelysomethingelse=''aaaa'')) 
AND 
b.anotherdifferentsomething != 41 
AND 
c.yetanotherdifferentthing LIKE(''%@%'') 
AND 
c.datafromvariablewannabe = (@i) 
GROUP BY 
... 
ORDER BY 
... 
OPTION(OPTIMIZE FOR(@i = ''' + @tmp + '''))' 
EXEC SP_EXECUTESQL @SQL, N'@i NVARCHAR(255)', @i = @tmp 
+0

이것은 내가 찾고있는 해답이다. 여전히 @i 변수에 따옴표를 추가해야했습니다. 그래서 그것은 다음과 같아야합니다 : 'DECLARE @i nvARCHAR (10) SET @i = '' 'POL' ''' – M3How

+0

더 많은 것이 있습니다. 여기에'option (optim for @i) '을 추가하고 싶다면 어디서 어떻게해야합니까? 이 특별한 경우. – M3How

+1

ORDER BY Ref : https://msdn.microsoft.com/en-us/library/ms181714.aspx 다음은 하나의 쿼리 문에만 적용됩니다 (마지막에 SELECT 문을 넣어야 함) – mortb

1

작업 솔루션 :

DECLARE @i NVARCHAR(255) 
declare @tmp nvarchar(255) 
SET @tmp = 'POL' 

DECLARE @SQL nVARCHAR(MAX) 
SET @sql = 'SELECT 

a.something1, 
b.something2, 
c.something3 

FROM 
aaa a WITH(NOLOCK) 
LEFT JOIN bbb b WITH(NOLOCK) ON.... 
LEFT JOIN ccc c WITH(NOLOCK) ON.... 

WHERE 
a.somethingelse = ''aa'' 
AND 
((a.entirelysomethingelse=''aaa'') 
OR 
(a.entirelysomethingelse=''aaaa'')) 
AND 
b.anotherdifferentsomething != 41 
AND 
c.yetanotherdifferentthing LIKE(''%@%'') 
AND 
c.datafromvariablewannabe = (@i) 

GROUP BY 
... 
ORDER BY 
... 

OPTION(OPTIMIZE FOR(@i = ''' + @tmp + '''))' 

EXECUTE SP_EXECUTESQL @SQL, N'@i NVARCHAR(255)', @i = @tmp 

이 변수 @temp를 선언하지 않고 일을하지 않았다. 그 후에 나는 Exec과 관련된 문제가 발생했다. @mortb 제안대로 SP_EXECUTESQL을 사용할 수 없습니다. SP_EXECUTESQL 전에 EXECUTE을 사용해야했고 그 게시물 Why do I get "Procedure expects parameter '@statement' of type 'ntext/nchar/nvarchar'." when I try to use sp_executesql?에서 다음 오류와 관련된 정보를 발견했습니다. 쿼리 변수의 형식을 변경하고 대괄호를 사용하지 않아야했습니다. 나는 새 변수를 만들어야했습니다 왜 내가 좋아하는 것이 여전히

알고하고 코드의이 부분에 대해 조금 더 알고있는 것이 도움이 될 것입니다 : 지금

OPTION(OPTIMIZE FOR(@i = ''' + @tmp + '''))' 

EXECUTE SP_EXECUTESQL @SQL, N'@i NVARCHAR(255)', @i = @tmp 

그것은 작동을하지만, 내가 좋아하는 것 왜, 어떻게 알았습니까?

+0

위의 답에 편집 내용을 추가했습니다. – mortb

+1

'SP_EXECUTESQL'는 SQL 문자열을 받아 지정된 매개 변수로 실행하는 내장 내장 프로 시저입니다. sql을 문자열로 만들 때 처음에는 혼란 스럽습니다. 'N'@ NVARCHAR (255) ', @i = @ tmp' 부분은 sql 텍스트에'@ i'와'@i'라는 ​​매개 변수가 있음을 저장 프로 시저에 알려줍니다 (텍스트 실행)은 같은 값을 가져야한다. @ tmp는 텍스트 외부에있다. OPTION (OPTIMIZE FOR (@i = '' '+ @tmp +' '))'부분은 텍스트가 *'@ tmp'의 값을 포함한다는 것을 의미합니다. 'SP_EXECUTESQL'에 입력). – mortb

+1

시간을 좀주세요. 이해할 수 있습니다. – mortb

관련 문제