我尝试了以下操作:
declare @var2 nvarchar(30)
declare @qsql nvarchar(100)
set @var2 = N'iddelegat'
exec ('select max('+ @var2 + ') as IDexec from delegat');
set @qsql = 'select max(@varsp) as IDspexec from delegat';
exec sp_executesql @qsql, N'@varsp nvarchar(30)', @var2;
结果:
IDexec IDspexec
-----------------------
500038 iddelegat
我不明白为什么sp_executesql
没有返回与EXECUTE
相同的结果。右侧返回的值仅在EXECUTE
语句中。sp_executesql
似乎没有计算字符串"iddelegat"以返回该列。
使用sp_executesql
时不能参数化列名或表名。因此,当您在exec()
中插入值iddelegat
时,您就得到了列。当您将它作为sp_executesql
的参数时,您得到的是'iddelegat'
——一个具有列名称的字符串。
SQL文档中没有很好地解释可以参数化什么的问题。如果你挖得足够远,你会得到这个:
您可以在哪里使用参数
您可以将参数用作文字值的占位符,用于文本或数值。最常见的情况是,参数用作单个行或组的搜索条件中的占位符(即在SQL语句的WHERE或HAVING子句中)。
这是文档中一个模糊的部分,但它有正确的总体思想。
为了帮助进一步理解这一点,SQL引擎可以编译带有参数的查询来获得执行计划。要做到这一点,它需要知道查询中的实际列和表。额外的值——参数——可以在编译步骤之后插入。
不能参数化列名。
您的尝试基本上与执行MAX(N'iddelegat')
而非MAX(iddelegat)
相同
在动态SQL中使用这些方法的唯一方法是将它们直接连接到字符串中。
如果这样做是为了减少SQL注入的可能性,那么应该使用quotename
函数。
请参阅动态SQL 的诅咒和祝福