sql - 存储过程中动态形成的 SQL 是否否定了存储过程的真正目的?

标签 sql sql-server tsql

我们现在有 10-12 年的旧项目。它使用的是 SQL2000,我们现在已迁移到 SQL2008。

在执行此任务时,我发现存储过程接受参数,然后将查询构造为字符串,然后使用 EXEC 执行命令。

CREATE PROCEDURE MyProc
  (@TableName varchar(255),
   @FirstName varchar(50),
   @LastName varchar(50))
AS

    -- Create a variable @SQLStatement
    DECLARE @SQLStatement varchar(255)

    -- Enter the dynamic SQL statement into the
    -- variable @SQLStatement
    SELECT @SQLStatement = "SELECT * FROM " +
                   @TableName + "WHERE FirstName = '"
                   + @FirstName + "' AND LastName = '"
                   + @LastName + "'"

    -- Execute the SQL statement
    EXEC(@SQLStatement)

这是一个不好的方法吗?这是否会消除存储过程的好处(预编译查询的好处)?

最佳答案

不,我认为存储过程的主要好处不再是它是“预编译”的(从 2005 年或更早开始,也许从来没有,除了非常大量的调用)。

有一个计划缓存,也可用于临时语句。

这个特定的示例重新引入了一个注入(inject)漏洞,该漏洞将通过以下方式自动实现:

CREATE PROCEDURE MyProc
  (@FirstName varchar(50),
   @LastName varchar(50))
AS
BEGIN
    SELECT * FROM TABLENAME
    WHERE FirstName = @FirstName
        AND LastName = @LastName
END

所有这些都是为了在表名称上进行参数化。

存储过程的好处包括:

  • 安全管理(能够独立于 SELECT/INSERT/UPDATE 控制 EXEC 权限)

  • 访问协调(确保所有操作都以特定方式完成)

  • 组织(能够以连贯的方式组织数据库接口(interface))

  • 注入(inject)预防(存储过程总是参数化的,这确保调用者无法创建容易受到注入(inject)攻击的数据库案例 - 请注意,SP 本身需要正确编写,但客户端程序员将无法如果他们只能访问 SP 而不能访问表,则引入注入(inject))

  • 系统 list (能够按名称分析和优化某些过程,能够拥有由存储过程组成的全面且记录良好的界面层)

动态 SQL 在 SP 中占有一席之地,它可以否定一些东西 - 例如安全性(它启动一个新链,因此需要在此处授予 SELECT 权限)和注入(inject)。执行计划缓存不是我优先考虑的一个。

关于sql - 存储过程中动态形成的 SQL 是否否定了存储过程的真正目的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5597529/

相关文章:

sql - 如果传递 null 将引发错误的 TSQL 函数?

sql - 在oracle中查找星期几

mysql - 如何删除表中的记录以便每分钟有一个读数?

sql - 如何在 asp.net C# 中的 SQL Server 中获取 YY 格式的年份

sql-server - CTE 行号分区

sql-server - 用C#编写的SQL CLR DDL触发器

sql - 十进制到整数在SQL

sql - 使用SAS sql创建宏变量

tsql - 表变量和执行

sql-server - CASE 语句内 TSQL NVARCHAR 转换错误