2015-09-28 67 views
0

我需要刪除(讀取/更新)某些表中的某些值,並且希望使用存儲過程來減少安全問題。SQL Server存儲過程:動態刪除記錄

由於表很多,記錄更多,並且爲每個組合編寫存儲過程是不合理的,並且由於每個人都有這種需求,我認爲可以很容易地找到存儲過程來執行此操作。但是使用google搜索很多,我沒有找到一個簡單而簡短的答案,所以我嘗試構建自己的存儲過程。但恐怕它可能有一些安全問題:主要是當我宣佈@Tablenvarchar(30) ..我試圖宣佈爲表,但它返回錯誤..

可以建議什麼是不可接受的,並提出一個解決方案?

感謝

這裏存儲的程序刪除..但對於其他操作可能是相似的:

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 

感謝您閱讀 喬

+1

一個動態的過程刪除行...可能會出錯! –

+0

爲什麼這個代碼?爲什麼不在外鍵中使用CASCADE DELETE或者刪除相關記錄的TRIGGER?這不僅是安全問題。除非您在單個程序中調用* all *刪除,否則您將擁有殭屍條目。爲什麼不寫*一個*存儲過程刪除所有相關條目?您甚至可以使用代碼生成來創建刪除語句 –

+0

,這些都是簡單的表格,沒有相關記錄。基本上,表格中包含激活某個服務的用戶的名稱,用戶修改其自己的訂閱。 在任何情況下..從來沒有使用'CASCADE DELETE',但它可能會在其他情況下有用。 感謝您的意見。 – Joe

回答

1

你需要做的是這樣的:

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 

基本上,參數列表ca n只能引用實際嵌入在SQL字符串中的參數。

此外,請注意,@Table@WhereField會更爲正確,因爲數據類型爲sysname。我也可能限制了@UID,@PWD@WhereValueNOT NULL,因爲我討厭未處理的空值。

但是,您真的需要考慮是否要這樣做。對我來說,這感覺就像留下一把裝滿槍的躺在身邊。當你用一個恰好與dbo.subUsers表中的值一致的UID字段的表進行調用時發生了什麼,即使這裏沒有關係?我沒有看到這個方法比剛纔從你的應用程序運行參數化查詢有什麼顯着的優點,並且查詢在執行之間改變的事實意味着你可能遇到參數嗅探的問題,所以你最終可能會得到次優的執行計劃。

+0

感謝您的回答..以及是..輸入字段中有'NOT NULL',那麼..有什麼區別在EXEC中寫入@ @WhereValue = @WhereValue,@_UID = @UID,@_PWD = @ PWD'而不是簡單的,@WhereValue,@UID,@PWD? 由於預計將使用此sproc修改的表只有12個,可以幫助緩解檢查列表中是否包含@表格的風險? 我的恐懼只是把一把裝滿槍的小孩留給小孩..但其他的解決方案可以用'TableName'寫12 sproc已經設置.. 或者我不考慮什麼? 謝謝 – Joe

+0

@Joe好吧,這不僅僅是我將它改爲'@_WhereValue = @WhereValue,@_UID = @UID,@_PWD = @ PWD',這是我從@ Table和'WhereField'中消除了從@參數列表。一組固定的已知表格肯定有助於風險部分,但最終你還是會回到「這會增加什麼?爲什麼當你放棄編寫查詢的靈活性時這更容易?爲什麼?而不是應用程序中的一個函數,您可以在其中指定枚舉並驗證一些查詢?「我不是說按照你的方式來做這件事並不是錯的,但有些可能。這有點奇怪。 –