【问题标题】:T-SQL EXEC versus sp_execT-SQL EXEC 与 sp_exec
【发布时间】:2014-11-08 20:49:30
【问题描述】:

我尝试了以下方法:

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' 以返回该列。

【问题讨论】:

    标签: sql sql-server tsql execute sp-executesql


    【解决方案1】:

    使用sp_executesql 时不能参数化列名或表名。因此,当您在exec() 中插入值iddelegat 时,您将获得该列。当您将它作为sp_executesql 的参数时,您将获得'iddelegat' -- 一个带有列名的字符串。

    SQL 文档中没有很好地解释您可以参数化的问题。如果你dig far enough,你会得到这个:

    您可以在哪里使用参数

    您可以使用参数作为文字值的占位符—— 文本或数值。最常见的是,参数被用作 单个行或组的搜索条件中的占位符 (即在 SQL 语句的 WHERE 或 HAVING 子句中)。

    这在文档的一个不起眼的部分,但它具有正确的总体思路。

    为了帮助进一步理解这一点,SQL 引擎可以编译带有参数的查询以获取执行计划。为此,它需要知道查询中的实际列和表。额外的值——参数——可以在编译步骤之后插入。

    【讨论】:

      【解决方案2】:

      您不能参数化列名。

      你的尝试与MAX(N'iddelegat')而不是MAX(iddelegat)基本相同

      在动态 SQL 中使用它们的唯一方法是将它们直接连接到字符串中。

      如果这样做,您应该使用quotename 函数来减少 SQL 注入的可能性。

      The curses and blessings of dynamic SQL

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-10-07
        • 1970-01-01
        • 2018-06-13
        • 1970-01-01
        • 1970-01-01
        • 2023-03-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多