SQL Server存储过程:动态删除记录

时间:2015-09-28 04:13:17

标签: tsql stored-procedures dynamic

我需要删除(读取/更新)某些表中的某些值,并希望使用存储过程来减少安全问题。

由于表很多并且记录更多,并且为每个组合编写存储过程是不合理的,并且由于每个人都有这种需要,我认为可以很容易地找到存储过程来执行此操作。但谷歌搜索很多我没有找到一个简单而简短的答案,所以我尝试建立自己的存储过程。但我担心它可能存在一些安全问题:主要是当我将@Table声明为nvarchar(30)时..我试图将其声明为TABLE但它返回错误..

可以建议什么是不可接受的并提出解决方案吗?

由于

此处删除..但其他操作的存储过程可能类似:

CREATE PROCEDURE dbo.spDeleteRecord
(
    @UID        nvarchar(20) = NOT NULL,
    @PWD        nvarchar(30) = NOT NULL,
    @Table      sysname,
    @WhereField sysname,
    @WhereValue nvarchar(150) = NOT NULL
)
AS
    SET NOCOUNT ON;

    DECLARE @S nvarchar(max) = '',
            @P nvarchar(max) = ''

    SET @S = 'DELETE t
              from dbo.'+quotename(@Table)+' t 
              join dbo.subUsers su on t.UID = su.UID 
              where ' + quotename(@WhereField) + ' = @_WhereValue 
                and su.SUID = @_UID 
                and su.PWD = @_PWD'    

   SET @P = '@_UID nvarchar(50),
             @_PWD nvarchar(50),
             @_Table sysname,
             @_WhereField sysname,
             @_WhereValue nvarchar(150)'

   --PRINT @S
   EXEC sp_executesql @S, @P, @UID, @PWD, @Table, @WhereField, @WhereValue

   SET NOCOUNT OFF

感谢阅读 乔

1 个答案:

答案 0 :(得分:1)

你需要这样做:

SET @S = 'DELETE t
          from dbo.'+quotename(@Table)+' t 
          join dbo.subUsers su on t.UID = su.UID 
          where ' + quotename(@WhereField) + ' = @_WhereValue 
            and su.SUID = @_UID 
            and su.PWD = @_PWD'    

SET @P = '@_UID nvarchar(50),
         @_PWD nvarchar(50),
         @_WhereValue nvarchar(150)'

--PRINT @S
EXEC sp_executesql @S, @P, @_WhereValue = @WhereValue, @_UID = @UID, @_PWD = @PWD

基本上,参数列表只能引用实际嵌入在SQL字符串中的参数。

另请注意,@Table@WhereField作为数据类型sysname会更正确。我也可能将@UID@PWD@WhereValue限制为NOT NULL,因为我讨厌未处理的空值。

但是,你真的需要考虑是否要这样做。对我来说,感觉就像留下一把装满枪的枪。使用碰巧有UID字段恰好与dbo.subUsers表中的值重合的表来调用它时会发生什么情况,即使这里没有关系?我没有看到这种方法比从您的应用程序运行参数化查询有任何显着优势,而且查询在执行之间发生变化这一事实意味着您可能会遇到参数嗅探问题,因此您最终可能会遇到次优执行问题计划。