我尝试了以下内容:
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'来返回列。
答案 0 :(得分:2)
使用sp_executesql
时,无法参数化列名或表名。因此,当您在iddelegat
中插入值exec()
时,您将获得该列。当您将其作为sp_executesql
的参数时,您将获得'iddelegat'
- 一个包含该列名称的字符串。
SQL文档中没有很好地解释您可以参数化的问题。如果你dig far enough,你会得到这个:
您可以使用参数的位置
您可以使用参数作为文字值的占位符 - 两者之一 文字或数字值。最常见的是,参数用作 占位符在单个行或组的搜索条件中 (即,在SQL语句的WHERE或HAVING子句中)。
这是文档中一个不起眼的部分,但它有正确的一般概念。
为了帮助进一步理解这一点,SQL引擎可以使用参数编译查询以获取执行计划。为此,它需要知道查询中的实际列和表。在编译步骤之后,可以在中插入额外值 - 参数。
答案 1 :(得分:1)
您无法对列名称进行参数化。
您的尝试与MAX(N'iddelegat')
而非MAX(iddelegat)
在动态SQL中使用它们的唯一方法是将它们直接连接到字符串中。
如果这样做,您应该使用quotename
函数来减轻SQL注入的可能性。