簡體   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