场景:需要将n个参数传递给存储过程.其中一个论点是类型varchar(x).该varchar参数需要从少数其他varchar变量构造.此问题使用SQL Server 2005,但此行为适用于所有版本的SQL Server.
设置:
DECLARE @MyString varchar(500), @MyBar varchar(10), @MyFoo varchar(10)
SELECT @MyBar= 'baz '
SELECT @MyFoo= 'bat '
-- try calling this stored procedure!
EXEC DoSomeWork @MsgID, 'Hello ' + @MyBar + '" world! "' + @MyFoo + '".'
Run Code Online (Sandbox Code Playgroud)
这在SQL Server中产生异常:Incorrect syntax near '+'.通常,您可能认为数据类型是错误的(即变量属于不同类型,但会产生不同的错误消息).
这是一个没有错误编译的正确实现:
SELECT @MyString= 'Hello ' + @MyBar + '" world! "' + @MyFoo + '".';
EXEC DoSomeWork @ID, @MyString
Run Code Online (Sandbox Code Playgroud)
问题:为什么 T-SQL无法处理varchar作为参数的串联?它知道类型,因为它们被正确地声明为varchar.
鉴于下表:
USE tempdb;
CREATE TABLE #T(Val INT);
INSERT INTO #T VALUES (1), (2), (3), (4), (5);
Run Code Online (Sandbox Code Playgroud)
我想使用EXEC给定的Val值执行动态sql查询:
DECLARE @sql NVARCHAR(MAX);
DECLARE @Val INT = 3;
EXEC ('SELECT * FROM #T WHERE Val = ' + @Val);
Run Code Online (Sandbox Code Playgroud)
执行时没有错误,并给出正确的结果.
我的假设是这会产生错误:
将varchar值'SELECT*FROM #T WHERE Val ='转换为数据类型int时转换失败.
由于@Val是INT数据类型和数据类型优先级的规则,因此EXEC必须将其中的查询转换为INT.
我的问题是为什么没有EXEC产生转换错误的调用?
笔记:
- 我知道sp_executesql.我也不是在寻求替代方案.我只是要求解释为什么没有产生错误.
-这个问题的答案的问题似乎并没有解释我的情况的问题,是指VARCHAR以VARCHAR串联.