【问题标题】:What is the advantage of using @ParmDefinition in sp_executesql在 sp_executesql 中使用 @ParmDefinition 有什么好处
【发布时间】:2015-10-18 16:15:17
【问题描述】:
DECLARE @id int
DECLARE @name nvarchar(20)
SET @id = 5
SET @name = 'Paul'

这两个选项有什么区别:

Set @SQLQueryInnen = 'SELECT * FROM someTable WHERE ID = ' + @id + ' AND NAME = ''' + @name + ''''
Execute sp_Executesql @SQLQueryInnen

Set @SQLQueryInnen = 'SELECT * FROM someTable WHERE ID = @id AND NAME = @name'
Set @ParmDefinition = '@id int, @name nvarchar(20)'
Execute sp_Executesql @SQLQueryInnen, @ParmDefinition, @id

到目前为止,在使用@ParmDefinition 时,我只看到两次声明@id 和@name 的数据类型的开销。另一方面,使用@ParamDefinition 似乎更容易“构建字符串”。

【问题讨论】:

  • 第二个参数化了您的查询,有助于防止 SQL 注入。

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


【解决方案1】:

您避免使用 stringly 类型的代码 - 您必须将所有内容转换为字符串,以便将其推入 @SQLQueryInnen 参数,然后引入问题,因为您必须解决如何安全、明确地将字符串转换回正确的原始数据类型。

对于ints,转换问题不是很明显。但是,如果您查看人们报告的问题数量(此处和其他论坛),他们在 datetimes 和字符串之间转换时遇到问题,您会发现它确实会导致真正的问题。最好始终将数据保持为其自然类型。

【讨论】:

    【解决方案2】:

    第一种情况很容易发生 SQL 注入并且存在安全风险。讨论到此为止。

    【讨论】:

    • ja,我以前听说过这个词,但从来没有真正尝试过理解它的含义,现在我知道它在第一种情况下有多危险......
    【解决方案3】:

    我看到没有人提到最重要的事情之一。当您使用参数化查询时,您的执行计划会被缓存。

    您的查询,即:

    SELECT *
    FROM someTable
    WHERE ID = @id
        AND NAME = @name;
    

    它的执行计划将存储在内存中,每次查询时都会重复使用它(这是一个很大的好处)。同时,如果您使用这样的字符串连接生成代码:

    Set @SQLQueryInnen = 'SELECT * FROM someTable WHERE ID = ' + @id + ' AND NAME = ''' + @name + ''''
    Execute sp_Executesql @SQLQueryInnen
    

    您的代码将为每个参数组合生成执行计划(除非它是重复的),并且不会重复使用缓存的计划。假设您正在传递@Id = 1@Name = 'Paul',您生成的查询将如下所示:

    SELECT *
    FROM someTable
    WHERE ID = 5
        AND NAME = 'Paul';
    

    如果您将名称更改为'Rob',您生成的查询将如下所示,SQL Server 必须为其创建一个新计划:

    SELECT *
    FROM someTable
    WHERE ID = 5
        AND NAME = 'Rob';
    

    意义计划不会被重复使用。希望对您有所帮助。

    这是一篇更详细地解释这一点的文章:EXEC vs. sp_executeSQL(不要依赖文章标题,它解释了您在问题上提出的确切差异)。引用自它:

    TSQL 字符串只构建一次,之后每次都一样 使用 sp_executesql 调用查询,SQL Server 检索查询 从缓存中规划并重用它

    【讨论】:

      猜你喜欢
      • 2012-01-21
      • 2011-01-15
      • 2016-01-30
      • 2019-01-16
      • 2018-01-22
      • 2016-06-27
      • 2016-11-05
      • 2015-11-05
      • 1970-01-01
      相关资源
      最近更新 更多