简体   繁体   English

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

[英]How to create a stored procedure to delete full data from dynamic table

I'm trying to create a stored procedure to delete all data from dynamically selected tables. 我正在尝试创建一个存储过程,以从动态选择的表中删除所有数据。

I used this code, but it's not working. 我使用了此代码,但无法正常工作。 Any suggestion? 有什么建议吗?

CREATE PROCEDURE spDynamicDeleteTable
    @table NVARCHAR(100)
AS
BEGIN
    DECLARE @Sql NVARCHAR(MAX)

    SET @Sql= 'DELETE FROM'+ @table
    EXECUTE sp_executesql @Sql
END

You are missing a space. 您缺少空格。

Set @Sql= 'Delete from'+ @table

would become 会成为

Delete fromelbat

if @table = 'elbat' . 如果@table = 'elbat' That isn't valid syntax. 那是无效的语法。

Add a space after "from". 在“ from”之后添加一个空格。 It's also advisable to use quotename() to prevent funny things from happen with unusual table names. 最好使用quotename()防止有趣的事情在不寻常的表名下发生。

Set @Sql= 'Delete from ' + quotename(@table)

Some further notes: 其他注意事项:

  • @table should better be declared as a sysname rather than nvarchar(100) . 最好将@table声明为sysname而不是nvarchar(100) sysname is a type extra for object names. sysname是对象名称的额外类型。

  • Be aware, that you have to take great care regarding the rights this stored procedure is executed with in order to prevent it from being abused to delete arbitrary data. 请注意,必须非常注意执行此存储过程的权限,以防止滥用该存储过程删除任意数据。

This will protect against sql injections and also allow you to supply the schema as an optional parameter 这将防止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

Firstly, with regards to dynamic SQL you are opening yourself up to SQL Injection , and the issue you are seeing is due to the lack of the space as mentioned in the other answer and comments. 首先,关于动态SQL,您正在向SQL Injection开放,而您看到的问题是由于缺少其他答案和评论中提到的空间所致。

But.... 但....

While you could do something like this, you are potentially going to encounter issues when you try to run it, mainly related to referential integrity. 尽管您可以执行类似的操作,但是在尝试运行它时可能会遇到问题,主要与引用完整性有关。

Take this example: 举个例子:

User Table 用户表

UserId | Name
1      | Bob
2      | Jim

UserOrders Table UserOrders表

OrderId | UserId
1       | 1
2       | 1
3       | 2
4       | 2

Say you are going to delete all records in the User table. 假设您要删除“ User表中的所有记录。 The User table may have related information in UserOrders , so because the second table links to the primary key on the first table, you won't be able to delete records in the first table unless all related data is deleted, and the only way to do that is with cascade deletes, which is where this type of solution will become dangerous. User表可能在UserOrders具有相关信息,因此,由于第二个表链接到第一个表的主键,除非删除所有相关数据,否则您将无法删除第一个表中的记录,并且唯一的方法是使用级联删除来执行此操作,这将使这种解决方案变得危险。

If you're only concerned about static, un-linked data, then it could work, but if there are relationships between the tables then I would advise against this type of solution. 如果只关心静态的,未链接的数据,则可以使用它,但是如果表之间存在关系,则建议不要使用这种解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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