簡體   English   中英

創建用於通過case語句更新列的存儲過程

[英]Creating stored procedure for updating columns by case statement

我知道對此有很多問題,但是我找不到答案。

我有一個看起來像這樣的表:

+----+--------+--------+----------+
| ID | FormID | ItemID | StrataID |  
+----+--------+--------+----------+
| a  | b      |   1111 | NULL     |  
| a  | b      |   2222 | NULL     |  
| a  | b      |   3333 | NULL     |  
| a  | g      |   4563 | NULL     |  
| b  | f      |   6666 | NULL     |  
+----+--------+--------+----------+

我想根據其ID + FormID + ItemID更新StrataID的值。 我要插入的值未存儲在數據庫的任何表中,它們只是我擁有的單獨列表。 如果我使用常規case語句更新表,則它看起來像這樣:

 UPDATE [Table1]
    SET [StrataID] = 
        CASE ([ItemID])
            when 111  then 1
            when 222 then 2
            when 333 then 5
        else [StrataID]
        END 
WHERE [ID] = 'a'and [FormID] = 'b'

所以最終結果是:

+----+--------+--------+----------+--+
| ID | FormID | ItemID | StrataID |  |
+----+--------+--------+----------+--+
| a  | b      |   1111 | 1        |  |
| a  | b      |   2222 | 2        |  |
| a  | b      |   3333 | 5        |  |
| a  | g      |   4563 | NULL     |  |
| b  | f      |   6666 | NULL     |  |
+----+--------+--------+-------

但是我想避免為每個FormID復制case語句,因為我有2000多個記錄以這種方式更新。

我嘗試了以下動態SQL,其中@ColumnName是特定ID + FormID的所有可用FormID,而@NewValue是我想插入到'StrataID'字段而不是NULLS的值的字符串:

DECLARE @DynamicPivotQuery AS NVARCHAR(MAX)
DECLARE @ColumnName AS NVARCHAR(MAX)
DECLARE @NewValue AS NVARCHAR(MAX)


SELECT @ColumnName = STUFF((SELECT distinct  ',' +  QUOTENAME(ItemID)
                      FROM [Table1] 
                      where [ID] = 'a'and [FormID] = 'b'
                      FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)') , 1, 1, '');

SET @NewValue = ',1,2,5,';


SET @DynamicPivotQuery = 

    'UPDATE [Table1] SET [StrataID] = '+@NewValue+'
     WHERE[ID] = ''a'' and [FormID] = ''b'' AND ItemID ='+@ColumnName+';' 

--Execute the Dynamic Query
EXEC sp_executesql @DynamicPivotQuery

當我嘗試執行它時,出現錯誤-

Msg 137, Level 15, State 2, Line 18
Must declare the scalar variable "@NewValue".

我知道它可能會將@NewValue視為字符串而不是整數,但是我不確定如何將需要設置為新值的值存儲為不同的值,以及如何從重復的case語句創建動態sql語句。

關於如何將我的sql轉換為動態更新sql的任何建議? 提前致謝!!

連接零件以形成動態查詢時,您需要確保所有內容均為nvarchar類型,否則會出錯。 因此,您應該使用以下代碼,而不是當前的代碼。

請注意,下面的代碼將所有參數值強制轉換為nvarchar數據類型。

SET @DynamicPivotQuery = 

        'UPDATE [Table1] SET [StrataID] = '+ cast(@NewValue as nvarchar(100)) +'
         WHERE[ID] = ''a'' and [FormID] = ''b'' 
           AND ItemID ='+ cast( @ColumnName as nvarchar(500)) +';'

但是,您不需要動態查詢即可解決您的情況。 而是遵循以下方法。

  1. 在這種方法中,你收集表變量的所有項目Id的值@ItemValues ,並在表varaible相應StrataId值@StrataIDValues
  2. 確保兩個表中值的順序相同,以便@ItemValues表中的第一條記錄與@StrataIdValues表中的第一條記錄相對應。

    無需動態查詢即可更新

     DECLARE @ItemValues TABLE ( SequenceNumber int IDENTITY (1, 1), ItemID int ) INSERT INTO @ItemValues (ItemID) SELECT ItemId FROM Table1 WHERE [ID] = 'a' AND [FormID] = 'b'; --populate the corresponding values for StrataID in same sequence as --ItemId values in above table DECLARE @StrataIDValues TABLE ( SequenceNumber int IDENTITY (1, 1), StrataID int ) INSERT INTO @StrataIDValues (StrataID) VALUES (1), (2), (5); UPDATE [Table1] SET [StrataID] = v.StrataID FROM Table1 t INNER JOIN (SELECT ItemID, StrataID FROM @ItemValues INNER JOIN @StrataIDValues ON [@ItemValues].SequenceNumber = [@StrataIDValues].SequenceNumber) v ON t.ItemID = v.ItemID; 

通過查看查詢,我注意到的第一件事是,更新列值和ItemID缺少單引號應為IN而不是=,因為您有多個列名。 它應該是“ SET [StrataID] =``+ @ NewValue +''WHERE [ID] =``a''和[FormID] =``b''[SectionID] = 1 AND ItemID IN'+ @ ColumnName +'; “

打印@DynamicPivotQuery並執行以查看實際錯誤是什么。 同時發送實際的更新語句和錯誤以查找問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM