SQL 服务器存储过程:动态删除记录
SQL Server stored procedure: delete record dynamically
我需要删除(read/update)一些表中的一些值,并想使用存储过程来减少安全问题。
因为表很多,记录更多,每个组合都写一个存储过程是不合理的,既然大家都有这种需求,我想找一个存储过程来做这个应该很容易..但是谷歌搜索了很多我没有找到一个简单而简短的答案,所以我尝试构建我自己的存储过程。但我担心它可能有一些安全问题:主要是当我将 @Table
声明为 nvarchar(30)
.. 我试图声明为 TABLE 但它 returns 错误..
可以提出不可接受的地方并提出解决方案吗?
谢谢
这里是删除的存储过程..但其他操作可能类似:
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
感谢阅读
乔
您需要这样做:
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
,因为我讨厌未处理的空值。
不过,要不要做这件事,你真的需要考虑一下。对我来说,这感觉就像把上膛的枪放在身边。当你用一个 table 调用它时会发生什么,它恰好有一个 UID
字段恰好与 dbo.subUsers
table 中的值一致,即使那里不存在任何关系?我没有看到这种方法比仅 运行 从您的应用程序参数化查询有任何显着优势,而且查询在执行之间发生变化这一事实意味着您可能 运行 遇到参数嗅探问题所以您最终可能会得到次优的执行计划。
我需要删除(read/update)一些表中的一些值,并想使用存储过程来减少安全问题。
因为表很多,记录更多,每个组合都写一个存储过程是不合理的,既然大家都有这种需求,我想找一个存储过程来做这个应该很容易..但是谷歌搜索了很多我没有找到一个简单而简短的答案,所以我尝试构建我自己的存储过程。但我担心它可能有一些安全问题:主要是当我将 @Table
声明为 nvarchar(30)
.. 我试图声明为 TABLE 但它 returns 错误..
可以提出不可接受的地方并提出解决方案吗?
谢谢
这里是删除的存储过程..但其他操作可能类似:
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
感谢阅读 乔
您需要这样做:
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
,因为我讨厌未处理的空值。
不过,要不要做这件事,你真的需要考虑一下。对我来说,这感觉就像把上膛的枪放在身边。当你用一个 table 调用它时会发生什么,它恰好有一个 UID
字段恰好与 dbo.subUsers
table 中的值一致,即使那里不存在任何关系?我没有看到这种方法比仅 运行 从您的应用程序参数化查询有任何显着优势,而且查询在执行之间发生变化这一事实意味着您可能 运行 遇到参数嗅探问题所以您最终可能会得到次优的执行计划。