【问题标题】:IF condition not working in triggerIF条件在触发器中不起作用
【发布时间】:2016-09-13 08:20:20
【问题描述】:

我有一个触发器,用于管理来自另一个表的批量加载。将大量行插入到 Projects 表中时。触发器被触发,但是当插入的表中已经存在行时,条件不起作用。

此触发器的目的是将插入到项目表中的新行插入到 vat_matrix 表中。如果 vat_matrix 表中存在行,则使用项目表中的新值更新它们。

我尝试了几个选项,发现游标是遍历插入行的唯一解决方案。这可行,但是我无法让 if 条件用于更新现有行。

有什么建议吗?

 SET ANSI_NULLS ON

GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[update_vat] ON [dbo].[projects]
FOR UPDATE, INSERT
AS

DECLARE @project AS VARCHAR(25)
DECLARE @client AS VARCHAR(25) 
DECLARE @dim2 AS VARCHAR(25)
DECLARE @period_from AS INT
DECLARE @period_to AS INT 
DECLARE @status AS CHAR(1)
DECLARE @user_id AS VARCHAR(25)
DECLARE @unit_id AS VARCHAR(25)
DECLARE @sequence_no AS INT 

SELECT @project = project,
@client = client,
@dim2 = dim2,
@period_from = period_from,
@period_to = period_to,
@status = status,
@user_id = user_id,
@unit_id = unit_id
FROM inserted

--FIND MAXIMUM VALUE FOR SEQUENCE NUMBER
SET @sequence_no = (SELECT MAX(v) FROM (SELECT sequence_no FROM agldefmatdet WHERE matrix_id = 11) AS value(v));

BEGIN

DECLARE tbl_cursor CURSOR LOCAL FOR

      SELECT project, client, dim2, period_from, period_to, status, user_id, unit_id FROM inserted


    SET NOCOUNT ON;

  IF EXISTS (SELECT * FROM inserted WHERE inserted.project = @project) AND NOT EXISTS (SELECT * FROM deleted WHERE deleted.project = @project)
  BEGIN

   OPEN tbl_cursor
    FETCH NEXT FROM tbl_cursor INTO @project, @client, @dim2, @period_from, @period_to, @status, @user_id, @unit_id

    WHILE @@FETCH_STATUS = 0
    BEGIN

    INSERT INTO [dbo].[vat_matrix] 
        (att_val_from_1, 
            att_val_from_2,
            att_val_from_3,
            att_val_from_4,
            att_val_to_1,
            att_val_to_2,
            att_val_to_3,
            att_val_to_4, 
            att_value_1,
            att_value_2,
            att_value_3,
            att_value_4, 
            client, 
            dim_value, 
            last_update, 
            matrix_id, 
            period_from,
            period_to,
            sequence_no,
            status, 
            user_id)
    SELECT @project, 
            '', 
            '',
            '', 
            @project, 
            '', 
            '',
            '',
            @project, 
            '', 
            '',
            '',
            @client, 
            @dim2, 
            GETDATE(), 
            '11',
            '0',
            '0',
            @sequence_no + 1, 
            @status, 
            @user_id

      FETCH NEXT FROM tbl_cursor INTO @project, @client, @dim2, @period_from, @period_to, @status, @user_id, @unit_id

    --RETURN;

    END

    CLOSE tbl_cursor
    DEALLOCATE tbl_cursor

END

  IF EXISTS (SELECT * FROM inserted WHERE inserted.project = @project) AND EXISTS (SELECT * FROM deleted WHERE deleted.project = @project)
  BEGIN

  OPEN tbl_cursor
    FETCH NEXT FROM tbl_cursor INTO @project, @client, @dim2, @period_from, @period_to, @status, @user_id, @unit_id

    WHILE @@FETCH_STATUS = 0
    BEGIN

    UPDATE vat_matrix
      SET dim_value = @dim2,
                last_update = GETDATE(),
                period_from = @period_from, 
                period_to = @period_to,
                status = @status,
                user_id = @user_id
                WHERE att_val_from_1 = @project 
                AND matrix_id = '11' 
                AND client = 'LU'

      FETCH NEXT FROM tbl_cursor INTO @project, @client, @dim2, @period_from, @period_to, @status, @user_id, @unit_id
    END

    CLOSE tbl_cursor
    DEALLOCATE tbl_cursor

    --RETURN;
END



END;

【问题讨论】:

  • CURSORTrigger 内。看起来是个坏主意
  • 我发现它是在跳跳虎中遍历插入表中的新行的唯一方法。现在唯一的问题是 if 条件

标签: sql-server if-statement triggers cursor


【解决方案1】:

正如您所说,您的触发器仅在一次插入一行时才起作用。尝试使用此触发器

ALTER TRIGGER [dbo].[update_vat] 
ON [dbo].[projects] 
FOR UPDATE, INSERT 
AS 
  BEGIN 
      DECLARE @sequence_no AS INT 

      --FIND MAXIMUM VALUE FOR SEQUENCE NUMBER  
      SET @sequence_no = (SELECT Max(sequence_no)
                                  FROM   agldefmatdet 
                                  WHERE  matrix_id = 11)); 

      IF EXISTS (SELECT * 
                 FROM   inserted) 
         AND NOT EXISTS (SELECT * 
                         FROM   deleted) 
        BEGIN 
            INSERT INTO [dbo].[vat_matrix] 
                        (att_val_from_1, 
                         att_val_from_2, 
                         att_val_from_3, 
                         att_val_from_4, 
                         .....
                         user_id) 
            SELECT project, 
                   '', 
                   '', 
                   '', 
                   .....
                   user_id 
            FROM   inserted 
        END 

      IF EXISTS (SELECT * 
                 FROM   inserted) 
         AND EXISTS (SELECT * 
                     FROM   deleted) 
        BEGIN 
            UPDATE V 
            SET    dim_value = i.dim2, 
                   last_update = Getdate(), 
                   period_from = i.period_from, 
                   period_to = i.period_to, 
                   status = i.status, 
                   user_id = i.user_id 
            FROM   vat_matrix V 
                   JOIN inserted i 
                     ON v.att_val_from_1 = i.project 
            WHERE  matrix_id = '11' 
                   AND client = 'LU' 
        --RETURN;  
        END 
  END 

【讨论】:

  • 感谢 Prdp,不幸的是,这只会在 vat_matrix 表中添加一行,但会从批量插入中添加项目表中的所有行。这就是游标的原因,因为触发器每 5 行只插入一次。
  • @user3565164 - 我在您当前的触发器中找不到该条件。我的代码和你的触发器一样。除了它也可以在语句级别工作
  • 您好 Prdp,感谢您的回复。抱歉 - 这有效,但增值税矩阵中的现有行不会更新。他们只是再次被添加 - 项目表也是如此。它快把我逼疯了!
  • @user3565164 - 根据您的触发器,vat_matrix 表只有在您更新 projects 表时才会更新
  • 嗨 Prpd,是的,没错 - 所以当我将行导入项目表时,插入而不是更新相同的行。我只是依赖是否需要检查项目表而不是矩阵表?
猜你喜欢
  • 2016-01-22
  • 1970-01-01
  • 2014-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-11
  • 2016-08-13
  • 1970-01-01
相关资源
最近更新 更多