繁体   English   中英

如何创建存储过程以从动态表中删除完整数据

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM