[英]How to create a stored procedure to delete full data from dynamic table
我正在尝试创建一个存储过程,以从动态选择的表中删除所有数据。
我使用了此代码,但无法正常工作。 有什么建议吗?
CREATE PROCEDURE spDynamicDeleteTable
@table NVARCHAR(100)
AS
BEGIN
DECLARE @Sql NVARCHAR(MAX)
SET @Sql= 'DELETE FROM'+ @table
EXECUTE sp_executesql @Sql
END
您缺少空格。
Set @Sql= 'Delete from'+ @table
会成为
Delete fromelbat
如果@table = 'elbat'
。 那是无效的语法。
在“ from”之后添加一个空格。 最好使用quotename()
防止有趣的事情在不寻常的表名下发生。
Set @Sql= 'Delete from ' + quotename(@table)
其他注意事项:
最好将@table
声明为sysname
而不是nvarchar(100)
。 sysname
是对象名称的额外类型。
请注意,必须非常注意执行此存储过程的权限,以防止滥用该存储过程删除任意数据。
这将防止sql注入,并且还允许您将架构作为可选参数提供
ALTER PROCEDURE spDynamicDeleteTable
@table nvarchar(128),
@schema nvarchar(128) = 'dbo'
AS
BEGIN
DECLARE @Sql NVARCHAR(MAX)
SELECT
@Sql= 'DELETE FROM '+ quotename(s.SCHEMA_NAME) + '.'+ quotename(t.NAME)
FROM sys.tables t
CROSS JOIN
[INFORMATION_SCHEMA].[SCHEMATA] s
WHERE
t.NAME = @table
and s.SCHEMA_NAME = @schema
IF @@rowcount = 1
EXECUTE sp_executesql @Sql
ELSE
print 'failed'
END
首先,关于动态SQL,您正在向SQL Injection开放,而您看到的问题是由于缺少其他答案和评论中提到的空间所致。
但....
尽管您可以执行类似的操作,但是在尝试运行它时可能会遇到问题,主要与引用完整性有关。
举个例子:
用户表
UserId | Name
1 | Bob
2 | Jim
UserOrders表
OrderId | UserId
1 | 1
2 | 1
3 | 2
4 | 2
假设您要删除“ User
表中的所有记录。 User
表可能在UserOrders
具有相关信息,因此,由于第二个表链接到第一个表的主键,除非删除所有相关数据,否则您将无法删除第一个表中的记录,并且唯一的方法是使用级联删除来执行此操作,这将使这种解决方案变得危险。
如果只关心静态的,未链接的数据,则可以使用它,但是如果表之间存在关系,则建议不要使用这种解决方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.