【问题标题】:Performing UPDATE with AFTER UPDATE trigger SQL Server 2008 R2使用 AFTER UPDATE 触发器 SQL Server 2008 R2 执行 UPDATE
【发布时间】:2014-10-09 12:40:44
【问题描述】:

我在 SQL Server 2008 R2 中有一个包含 1000 多条记录的表。有一个 SharePoint 2010 界面,用户可以实时更新此表的行,并且有一个字段 (CLASS) 应在更新一或两列(COUNTRY_REASON 或/和 VENDOR_REASON)时计算。

我正在考虑在更新时创建一个 AFTER UPDATE 触发器,但我想知道它是否不会进入某种循环?

有没有比使用触发器更好的方法来执行此更新?您有什么意见/建议?

CREATE TRIGGER [dbo].[TRG_NOSSCE_UPDATE_CLASS] 
ON [TO_BDB].[dbo].[to_bdb_nossce_comm_act] 
after UPDATE 
AS 
  BEGIN 
      UPDATE [TO_BDB].[dbo].[to_bdb_nossce_comm_act] 
      SET    class = CASE 
                       WHEN ( country_reason = '' OR country_reason IS NULL ) 
                            AND ( vendor_reason = '' OR vendor_reason IS NULL ) 
                       THEN 'NOT CLASSIFIED' 
                       WHEN country_reason = 'Vendor_Issue' 
                            AND ( vendor_reason = '' OR vendor_reason IS NULL ) 
                       THEN 'SITE ISSUE' 
                       WHEN country_reason = 'Vendor_Issue' 
                             OR country_reason = '' 
                             OR country_reason IS NULL 
                      THEN ( 
                         CASE 
                           WHEN vendor_reason IN ( 'Site Product Quality', 'Site QA Release' ) 
                           THEN 'SITE QUALITY' 
                           WHEN vendor_reason = 'Customer Order Management' 
                           THEN 'CPO SCM' 
                         WHEN vendor_reason LIKE 'Other%' THEN 'OTHER REASON' 
                         ELSE 'SITE SCM' 
                         END 
                       ) 
                       ELSE ( 
                         CASE 
                                WHEN country_reason IN ( 'Local Product Quality', 
                                                         'Local QA Release' 
                                                       ) 
                                THEN 'CPO QUALITY' 
                                WHEN country_reason IN ( 'Customs Clearance', 
                                                         'Transport Damage', 
                                                         'Transport Issue' ) 
                                THEN 'TRANSIT' 
                                WHEN country_reason IN ( 
                                     'Artwork', 'Complaince Checks', 
                                     'Registration', 
                                     'Safety Label Changes' ) 
                                THEN 'CPO LCM' 
                                WHEN country_reason = 'Vendor_Issue' 
                                THEN '' 
                                WHEN country_reason LIKE 'Other%' 
                                THEN 'OTHER REASON' 
                                ELSE 'CPO SCM' 
                          END 
                        ) 
                     END 
      WHERE  class = '' 
              OR class IS NULL 
                 AND Len(comment) > 0 
  END 

go 

【问题讨论】:

    标签: sql sql-server sql-server-2008 triggers sql-update


    【解决方案1】:

    您使用"INSTEAD OF INSERT,UPDATE" 并避免使用单个插入进行更新

    文章:

    试试这个!添加我评论过的其他列

    create  TRIGGER TRG_NOSSCE_UPDATE_CLASS
    ON [dbo].[to_bdb_nossce_comm_act]
    instead OF UPDATE
    AS
      BEGIN
          UPDATE a
          SET    a.class = CASE
                             WHEN ( a.country_reason = ''
                                     OR a.country_reason IS NULL )
                                  AND ( a.vendor_reason = ''
                                         OR a.vendor_reason IS NULL ) THEN 'NOT CLASSIFIED'
                             WHEN a.country_reason = 'Vendor_Issue'
                                  AND ( a.vendor_reason = ''
                                         OR a.vendor_reason IS NULL ) THEN 'SITE ISSUE'
                             WHEN a.country_reason = 'Vendor_Issue'
                                   OR a.country_reason = ''
                                   OR a.country_reason IS NULL THEN ( CASE
                                                                      WHEN a.vendor_reason IN ( 'Site Product Quality', 'Site QA Release' ) THEN 'SITE QUALITY'
                                                                      WHEN a.vendor_reason = 'Customer Order Management' THEN 'CPO SCM'
                                                                      WHEN a.vendor_reason LIKE 'Other%' THEN 'OTHER REASON'
                                                                      ELSE 'SITE SCM'
                                                                    END )
                             ELSE ( CASE
                                      WHEN a.country_reason IN ( 'Local Product Quality', 'Local QA Release' ) THEN 'CPO QUALITY'
                                      WHEN a.country_reason IN ( 'Customs Clearance', 'Transport Damage', 'Transport Issue' ) THEN 'TRANSIT'
                                      WHEN a.country_reason IN ( 'Artwork', 'Complaince Checks', 'Registration', 'Safety Label Changes' ) THEN 'CPO LCM'
                                      WHEN a.country_reason = 'Vendor_Issue' THEN ''
                                      WHEN a.country_reason LIKE 'Other%' THEN 'OTHER REASON'
                                      ELSE 'CPO SCM'
                                    END )
                           END
          --,
          --a.column1=b.column1,
          --a.othercolumns=b.othercolumns
          FROM   [dbo].[to_bdb_nossce_comm_act] a,
                 inserted b
          WHERE  a.class = ''
                  OR a.class IS NULL
                     AND Len(a.comment) > 0
      END
    
    go 
    

    假设你在你的 SP 中使用了一个游标,并且有 @class、@countryreason 和 @vendorreason 作为游标变量,我们可以这样做

    cursor loop....start
    SET   @class = CASE
                             WHEN ( @country_reason = ''
                                     OR @country_reason IS NULL )
                                  AND ( vendor_reason = ''
                                         OR @vendor_reason IS NULL ) THEN 'NOT CLASSIFIED'
                             WHEN @country_reason = 'Vendor_Issue'
                                  AND ( @vendor_reason = ''
                                         OR @vendor_reason IS NULL ) THEN 'SITE ISSUE'
                             WHEN @country_reason = 'Vendor_Issue'
                                   OR @country_reason = ''
                                   OR @country_reason IS NULL THEN ( CASE
                                                                      WHEN @vendor_reason IN ( 'Site Product Quality', 'Site QA Release' ) THEN 'SITE QUALITY'
                                                                      WHEN @vendor_reason = 'Customer Order Management' THEN 'CPO SCM'
                                                                      WHEN @vendor_reason LIKE 'Other%' THEN 'OTHER REASON'
                                                                      ELSE 'SITE SCM'
                                                                    END )
                             ELSE ( CASE
                                      WHEN @country_reason IN ( 'Local Product Quality', 'Local QA Release' ) THEN 'CPO QUALITY'
                                      WHEN @country_reason IN ( 'Customs Clearance', 'Transport Damage', 'Transport Issue' ) THEN 'TRANSIT'
                                      WHEN @country_reason IN ( 'Artwork', 'Complaince Checks', 'Registration', 'Safety Label Changes' ) THEN 'CPO LCM'
                                      WHEN @country_reason = 'Vendor_Issue' THEN ''
                                      WHEN @country_reason LIKE 'Other%' THEN 'OTHER REASON'
                                      ELSE 'CPO SCM'
                                    END )
                           END
    
    update table set other columns....,class=@class,.... where...
    
    close cursor loop
    

    只有分享一段或一瞥,SP才能更清楚。

    【讨论】:

    • 你好阿南德,谢谢!你能解释一下为什么这个解决方案对这种情况有好处吗?我阅读了几篇关于 INSTEAD OF 触发器的文章,它们几乎总是将其与视图相关联。我有一个大约。 1000 行表,SharePoint 将在用户更新行时执行更新。我希望触发器根据用户选择的值更新列(这些值随更新一起提供)。
    • 我们的目标是更新“类”字段。根据用户输入该行的原因,应该使用大小写进行更新。因此,我们不是让同一记录发生第一次更新,然后是第二次更新,而是停止并在传入记录中进行更改,并作为单个更新进行。
    • 不是以类似的方式将触发器附加到表中,而是执行其中的代码来代替原始更新语句。 www.databasejournal.com/features/mssql/article.php/1437741/Simplifying-Instead-Of-Triggers.htm
    • 好吧,雾越来越薄了:)!因此,“插入的 b”将是一个即将进行更新的虚拟表,在这种情况下与原始表(表 a)相同,我需要加入您评论过的所有列 --a.column1=b .column1 等等等等?
    • 参考这个 technet.microsoft.com/en-us/library/aa214435(v=sql.80).aspx 和是的加入列,如果有的话,你用来识别唯一的组合
    猜你喜欢
    • 2014-01-19
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多