【问题标题】:SQL Server TRIGGER IF Value Exist then Change it to Something elseSQL Server TRIGGER IF Value Exist 然后将其更改为其他内容
【发布时间】:2015-08-03 21:49:41
【问题描述】:

我有一张名为dbo.PBXDATA 的表。我想设置一个触发器,如果​​列 SALES_REP 的值等于特定值(int),则将该值更改为表列中 sales_rep 的名称。以下是我到目前为止所拥有的。任何提示都会很棒。谢谢。

CREATE TRIGGER dbo.PBXDATA_trgIUD_sales_rep
   ON  dbo.PBXDATA
   AFTER INSERT,UPDATE
AS 
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;
SELECT CAST(WHEN SALES_REP = '101'
THEN 'Ryan Kosterow'
ELSE 'NULL'
END as NVARCHAR) FROM dbo.PBXDATA

SELECT CAST(WHEN SALES_REP = '115'
THEN 'Robert Messing'
ELSE 'NULL'
END as NVARCHAR) FROM dbo.PBXDATA

SELECT CAST(WHEN SALES_REP = '114'
THEN 'Paul Clark'
ELSE 'NULL'
END as NVARCHAR) FROM dbo.PBXDATA

SELECT CAST(WHEN SALES_REP = '110'
THEN 'Aaron Townsley'
ELSE 'NULL'
END as NVARCHAR) FROM dbo.PBXDATA

END
GO

【问题讨论】:

    标签: sql-server database if-statement triggers


    【解决方案1】:

    我认为您的意思是执行 UPDATE 操作而不是 SELECT。同样,您实际上是在尝试使用 CASE 表达式,而您当前的语法 CAST(WHEN SALES_REP = '101' ... 是错误的。您可以尝试如下:

    UPDATE dbo.PBXDATA SET SALES_REP = CASE WHEN SALES_REP = '101' THEN 'Ryan Kosterow'
    WHEN SALES_REP = '115' THEN 'Robert Messing' 
    WHEN SALES_REP = '114' THEN 'Paul Clark'
    WHEN SALES_REP = '110' THEN 'Aaron Townsley'
    ELSE 'NULL' END
    

    【讨论】:

      【解决方案2】:

      您可以使用特殊的inserted 表来执行更新。该表将在触发器中可用,并将包含正在更新的行。这可能是代码:

      update inserted 
      set SALES_REP = 'Ryan Kosterow'
      where SALES_REP = '101'
      
      update inserted 
      set SALES_REP = 'Robert Messing'
      where SALES_REP = '115'
      
      update inserted 
      set SALES_REP = 'Paul Clerk'
      where SALES_REP = '114'
      
      update inserted 
      set SALES_REP = 'Aaron Townsley'
      where SALES_REP = '110'
      

      【讨论】:

      • 感谢您的帮助! :)
      【解决方案3】:

      这是一个糟糕的设计。您确实应该有一个 SALES_REP_NAMES 表,当您需要一个输出名称的查询时,您可以将其加入 PBXDATA 表。它看起来像

      SALES_REP_ID    NAME
      ------------    ----------------
      110             Aaron Townsley
      etc...
      

      你可以这样做:

      SELECT
        *
      FROM
        PBXDATA P
        JOIN SALES_REP_NAMES N
          ON P.SALES_REP = N.SALES_REP_ID
      

      但是,如果您真的想通过 TRIGGER 执行此操作,它应该如下所示。 请注意,它通过检查触发器是否需要执行更新来避免递归嵌套。

      CREATE TRIGGER dbo.PBXDATA_trgIUD_sales_rep ON dbo.PBXDATA
        AFTER INSERT, UPDATE
      AS
        BEGIN
          SET NOCOUNT ON;
          IF UPDATE(SALES_REP) 
            UPDATE
              p
            SET
              p.SALES_REP = CASE WHEN SALES_REP = '101' THEN 'Ryan Kosterow'
                               WHEN SALES_REP = '115' THEN 'Robert Messing'
                               WHEN SALES_REP = '114' THEN 'Paul Clark'
                               WHEN SALES_REP = '110' THEN 'Aaron Townsley'
                          END
            FROM
              INSERTED I
              JOIN PBXDATA P
                ON I.SALES_REP = P.SALES_REP
            WHERE
              I.SALES_REP IN ( '101', '115', '114', '110' )
      
        END 
      GO
      

      【讨论】:

      • 谢谢你。 :) 我确实按照您的建议为销售代表创建了一个表格。
      • OP 没有问任何数据库设计问题。同样在触发器中,不需要与PBXDATA 表进行连接;仅使用 inserted 表就足够了。
      • @srh 我注意到 OP 不同意你的观点。当你看到一个糟糕的设计时,你应该指出它。另外,请仔细考虑您的答案。更新 INSERTED 是徒劳的。如果您尝试,您将收到如下消息:Msg 286, Level 16, State 1, Procedure ThisTable_INSERT, Line 15 逻辑表 INSERTED 和 DELETED 无法更新。
      • 我原则上同意你应该指出不好的设计并提供帮助。但是我在这个论坛上看到的是,如果你试图提供帮助,那么有些人会因为偏离问题而给你负面评价。所以我认为这是一个原则。同意更新inserted 表并感谢您指出我的错误。我试图支持你的答案,但这个论坛不允许我这样做,除非你编辑你的答案。奇怪。
      • 感谢大家的帮助。我很感激你的所有意见。上次我做 T-SQL 是在 MSSQL Server 2005 是新的时候。再次感谢。
      猜你喜欢
      • 2014-06-21
      • 1970-01-01
      • 1970-01-01
      • 2014-07-05
      • 2013-09-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-07
      相关资源
      最近更新 更多