2016-06-16 2 views
8

을 생산하지 EXEC 내부 INT와 VARCHAR을 연결 오류가 발생하여 정확한 결과를 제공합니다. @ValINT 데이터 유형과 data type precedence의 규칙입니다은 다음 표 감안할 때 변환 오류

Conversion failed when converting the varchar value 'SELECT * FROM #T WHERE Val = ' to data type int.

때문에, EXEC 내부 쿼리가 INT으로 변환해야합니다 :

내 가정이 오류가 발생하는 것입니다.

제 질문은 EXEC으로 전화를 걸면 변환 오류가 발생하지 않는 이유는 무엇입니까?


참고 :

- 나는 약 sp_executesql을 알고있다. 나는 대안을 요구하지도 않는다. 왜 오류가 발생하지 않았는지에 대한 설명을 묻는 것입니다.

- 문제는 VARCHAR 연결에 VARCHAR을 의미로이 question에 대한 대답은 내 상황을 설명하지 않는 것 같습니다. 문자열 유형 int에서 암시 적 변환이 허용됩니다

+3

나는 믿을 수 없다. 이것은 구시대의 잔류 물이다. 다시 예를 들어 SQL Server 2000을 사용하면 여러 문자열을'+'함께 사용하여 EXEC 할 수 있습니다.이 문자열은 당시 varchar/nvarchar의 8000/4000 자 제한을 초과했습니다. 따라서 EXEC() 내부의'+'는 표준 문자열 연결 연산자가 아닌 것으로 믿습니다. 이 함수는 문자열 데이터 형식을 받아들이도록 지정되어 있지만 스트링 형식이 아닌 문자열 형식을 지정하고 데이터 우선 순위가 짧은 부두에서 벗어날 수 있습니다. 그러나 이것은 단지 추측이므로 대답이 아닙니다. –

+1

비슷한 질문이 이전에 요청되었습니다. http://stackoverflow.com/questions/26135174/type-conversion-in-exec-statement – Alex

+2

@Damien_The_Unbeliever, 매우 흥미로운 이론이 있습니다. 한 가지 관찰이 있습니다. 다음은 작동하지 않습니다. : EXEC ('SELECT'+ 3)하지만 'INT'변수와 연결하면됩니다. – Alex

답변

6

MSDN/BOL에 따르면, EXEC[UTE] 문에 대한 간단한 구문은 다음과 같습니다

Execute a character string 
{ EXEC | EXECUTE } 
    ({ @string_variable | [ N ]'tsql_string' } [ + ...n ]) 
    [ AS { USER } = ' name ' ] 
[;] 

@string_variable 
Is the name of a local variable. @string_variable can be any char, varchar, nchar, or nvarchar data type. These include the (max) data types. 

몇 가지 참고 사항 :이 줄 ({ @string_variable | [ N ] 'command_string [ ? ]' } [ **+** ...n ]에 따르면, 우리는이 EXEC (@var1 + @var2 + @var3) 같은 것을 쓸 수 있지만, 마지막 단락 SQL에 따라

1) 서버는 이러한 변수가 문자열 중 하나임을 예상합니다. char, varchar, nchar 또는 nvarchar.

2) 또한이 구문은 string variables (@string_variable | [ N ] 'command_string [ ? ]' } [ + ...n) 만 참조합니다. 나는 이것이 EXEC ('SELECT * FROM #T WHERE Val = ' + 3);가 실패하는 이유라고 생각한다 : 3은 변수가 아니다.

3)이 변수 중 하나에 위의 문자열 유형 중 하나가 없으면 SQL Server에서 암시 적 변환을 수행한다고 가정합니다. 나는 그것이 INT (예를 들어)에서 소스 변수를 NVARCHAR으로 변환한다고 가정합니다.이 문자열 유형 사이에 가장 높은 숫자는 data type precedence입니다.

4) 이것은 data type precedence이 작동하지 않는 유일한 장소는 아닙니다. ISNULL(param1, param2) 그것은 또 다른 예입니다. 이 경우 param2param1 데이터 유형으로 변환됩니다.

+2

네,'+'다음의 것은 문법상의 문자열 일뿐입니다. 그래서 연결 전에 문자열로 해석 될 것입니다. 사실'char','varchar','nchar' 또는'nvarchar'가 아닌 변수의 수용은 문서화되지 않은 것처럼 보이므로 아마도 피해야합니다. –

0

, 적어도까지 다시 SQL Server와 2008

참조 : Is there a way to turn off implicit type conversion in SQL Server?

편집 : Data Type Conversion (Database Engine)

당신은 암시 적 변환을 해제 할 수 없습니다 : 처음 썼습니다

'SELECT * FROM #T WHERE Val = ' + @Val is created before the call to EXEC .

나는 그렇게하지 못합니다. 그것에 대해 말하십시오. 이제는 EXEC에 대한 인수가 우리가 보았던 것과 다른 방식으로 구문 분석하는 DB 엔진의 일부로 전달되는 것으로 의심됩니다.

+1

이 문제는 암시 적 변환이 아니라 우선 순위입니다. 'int '는 우선 순위를 가지므로 SELECT * FROM #T WHERE Val ='+ @ Val'은 varchar에서 int 로의 변환 오류를 발생시킵니다. 그러나 EXEC는 다르게 동작합니다. –

+0

@PanagiotisKanavos 그럼에도 불구하고, 그것은 일어나고 있어야합니다. –

0

모든 MSDN은 EXEC [UTE]에 concatinating에 대해 말할 것입니다 :

the concatenation is performed logically in the SQL Server parser and never materializes in memory.

그래서 우리는 깊은 내부에 무엇을 SQL 서버에 대해 많이 알 수 없다. EXEC가 표현식을 인수로 받아들이지 않고 '+'로 구분 된 문자열 목록을 허용한다는 것만 알면됩니다.

Execute a character string 
{ EXEC | EXECUTE } 
    ({ @string_variable | [ N ]'tsql_string' } [ + ...n ]) 
    [ AS { LOGIN | USER } = ' name ' ] 
[;] 

그것은 바로 '+'문자로 구분 된 문자열이나 변수를 지원합니다 : 당신이 구문을 보면

. 따라서 실제로 EXEC에 식을 전달하지 않으므로 SQL Server 식 구문 분석기를 우회합니다.

+0

그러나 왜 int와 varchar의 연결이 오류를 발생시키지 않았습니까? –