SQL Server触发器和批量更新

时间:2015-09-16 18:52:16

标签: sql sql-server

我在SQL Server中有以下触发器:

CREATE TRIGGER Trig_UpdateSearch 
    ON nt_CadProduct  
    FOR  UPDATE
AS
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN
    DECLARE @CodProduct INT
    SET @CodProduct = (SELECT prdCod FROM INSERTED)

    DECLARE @DescSearch VARCHAR(500)
    SET @DescSearch = (SELECT CONVERT(VARCHAR(30),p.prdCod) +' '+ CONVERT(VARCHAR(255),p.prdDesc) +' '+ CONVERT(VARCHAR(255),p.prdCaract) +' '+ CONVERT(VARCHAR(30),p.prdCodFab) +' '+ CONVERT(VARCHAR(255),f.fabname) +' '+ CONVERT(VARCHAR(100),g.grpName)  +' '+ CONVERT(VARCHAR(100),a.agrpname) +' '+ CONVERT(VARCHAR(100),t.tpName) 
                       FROM nt_CadProduct AS p 
                       LEFT JOIN nt_cadFab AS f ON p.prdFab = f.fabcod 
                       LEFT JOIN nt_CadGp AS g ON p.prdGp = g.grpCod 
                       LEFT JOIN nt_cadagp AS a ON p.prdagp = a.agpcod 
                       LEFT JOIN nt_CadT AS t ON p.prdTb = t.tpCod 
                       WHERE prdCod = @CodProduct)

    UPDATE Index_nt_CadProduct
    SET IndexSearch = @DescSearch 
    WHERE IdProduct = @CodProduct

    IF @@ROWCOUNT = 0
        INSERT INTO Index_nt_CadProduct (IdProduct, IndexSearch) 
        VALUES (@CodProduct, @DescSearch)
END

单个更新工作正常但是如果我尝试批量更新它不起作用,因为子查询返回的值超过1,我尝试使用JOIN INSERTED而不是使用DECLARE,但它也不起作用。< / p>

我尝试了几种解决方案&#34;从其他SO答案中没有成功,因为我需要执行@DescSearch查询以返回concat结果

我已更改了列的名称,因此如果有任何拼写错误,请忽略它。实际触发功能

2 个答案:

答案 0 :(得分:1)

没有数据就很难,也许这就是你想要的:

CREATE TRIGGER Trig_UpdateSearch ON nt_CadProduct
  FOR UPDATE
AS
  SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
  BEGIN
    SELECT  distinct p.prdCod,
            CONVERT(VARCHAR(30), p.prdCod) + ' ' +
            CONVERT(VARCHAR(255), p.prdDesc) + ' ' +
            CONVERT(VARCHAR(255), p.prdCaract) + ' ' +
            CONVERT(VARCHAR(30), p.prdCodFab) + ' ' +
            CONVERT(VARCHAR(255), f.fabname) + ' ' +
            CONVERT(VARCHAR(100), g.grpName) + ' ' +
            CONVERT(VARCHAR(100), a.agrpname) + ' ' +
            CONVERT(VARCHAR(100), t.tpName) AS descSearch
    INTO    #tmp
    FROM    nt_CadProduct AS p
    LEFT JOIN nt_cadFab AS f ON p.prdFab = f.fabcod
    LEFT JOIN nt_CadGp AS g ON p.prdGp = g.grpCod
    LEFT JOIN nt_cadagp AS a ON p.prdagp = a.agpcod
    LEFT JOIN nt_CadT AS t ON p.prdTb = t.tpCod
    WHERE   prdCod IN ( SELECT  prdCod
                        FROM    inserted );

    WITH  x AS (
                 SELECT *
                 FROM   [#tmp] AS [t]
                 WHERE  EXISTS ( SELECT *
                                 FROM   Index_nt_CadProduct inp
                                 WHERE  t.prdCod = inp.IdProduct )
               )
      UPDATE  Index_nt_CadProduct
      SET     IndexSearch = x.descSearch
      FROM    x
      WHERE   IdProduct = x.prdCod;

    INSERT  INTO Index_nt_CadProduct ( IdProduct, IndexSearch )
    SELECT  prdCod, descSearch
    FROM    [#tmp] AS [t]
    WHERE   NOT EXISTS ( SELECT *
                         FROM   Index_nt_CadProduct inp
                         WHERE  t.prdCod = inp.IdProduct );
    drop table #tmp;
  END;

答案 1 :(得分:0)

您应该可以在没有临时表的情况下执行此操作。我不是百分之百的关于你到达那里的连接 - 尽我所能解析它。我认为它应该可以用于多个记录。给它一个测试

BEGIN
       UPDATE Index_nt_CadProduct
          SET IndexSearch = CONVERT(VARCHAR(30),nt_CadProduct.prdCod) +' '+ CONVERT(VARCHAR(255),nt_CadProduct.prdDesc) +' '+ CONVERT(VARCHAR(255),nt_CadProduct.prdCaract) +' '+ CONVERT(VARCHAR(30),nt_CadProduct.prdCodFab) +' '+ CONVERT(VARCHAR(255),f.fabname) +' '+ CONVERT(VARCHAR(100),g.grpName)  +' '+ CONVERT(VARCHAR(100),a.agrpname) +' '+ CONVERT(VARCHAR(100),t.tpName)
         FROM INSERTED
         JOIN Index_nt_CadProduct
           ON Index_nt_CadProduct.IdProduct = INSERTED.prdCod
         JOIN nt_CadProduct
           ON nt_CadProduct.prdCod = Index_nt_CadProduct.IdProduct
    LEFT JOIN nt_cadFab AS f ON nt_CadProduct.prdFab = f.fabcod 
    LEFT JOIN nt_CadGp AS g ON nt_CadProduct.prdGp = g.grpCod 
    LEFT JOIN nt_cadagp AS a ON nt_CadProduct.prdagp = a.agpcod 
    LEFT JOIN nt_CadT AS t ON nt_CadProduct.prdTb = t.tpCod 

    IF @@ROWCOUNT = 0
        INSERT INTO Index_nt_CadProduct (IdProduct, IndexSearch)
        SELECT INSERTED.prdCod
             , CONVERT(VARCHAR(30),nt_CadProduct.prdCod) +' '+ CONVERT(VARCHAR(255),nt_CadProduct.prdDesc) +' '+ CONVERT(VARCHAR(255),nt_CadProduct.prdCaract) +' '+ CONVERT(VARCHAR(30),nt_CadProduct.prdCodFab) +' '+ CONVERT(VARCHAR(255),f.fabname) +' '+ CONVERT(VARCHAR(100),g.grpName)  +' '+ CONVERT(VARCHAR(100),a.agrpname) +' '+ CONVERT(VARCHAR(100),t.tpName)
         FROM INSERTED
         JOIN Index_nt_CadProduct
           ON Index_nt_CadProduct.IdProduct = INSERTED.prdCod
         JOIN nt_CadProduct
           ON nt_CadProduct.prdCod = Index_nt_CadProduct.IdProduct
    LEFT JOIN nt_cadFab AS f ON nt_CadProduct.prdFab = f.fabcod 
    LEFT JOIN nt_CadGp AS g ON nt_CadProduct.prdGp = g.grpCod 
    LEFT JOIN nt_cadagp AS a ON nt_CadProduct.prdagp = a.agpcod 
    LEFT JOIN nt_CadT AS t ON nt_CadProduct.prdTb = t.tpCod 

END

...虽然我发现如果LEFT JOIN中的任何一个为空,那么长连接字符串将为null。