SQL:如果存在过程存在则更新

时间:2014-02-20 09:02:12

标签: sql-server tsql sql-server-2005

我需要一些SQL存储过程的帮助。我正在使用来自不同表的源填充中间表(COM_EXISTENCIAS)以用于报告目的。在第一步中,我使用COM_INVENTARIOS表中的数据填充它,该数据符合某些必要条件,如果有超过与冷冻管匹配的行,则将其分组为库存总和:

BEGIN
    INSERT  INTO COM_EXISTENCIAS
            (
              Mes ,
              Anyo ,
              Centro ,
              Codigo ,
              Stock ,
              Descripcion
            )
            SELECT  I.Mes ,
                    I.Anyo ,
                    I.Centro ,
                    I.Codigo ,
                    SUM(I.Stock) AS STOCK ,
                    I.Descripcion
            FROM    COM_INVENTARIOS I
            WHERE   I.Mes = @Mes
                    AND I.Centro = @Emp
                    AND I.NumInv = @NumInv
                    AND I.Anyo = @Anyo
            GROUP BY I.Codigo ,
                    I.Mes ,
                    I.Anyo ,
                    I.Centro ,
                    I.Descripcion
END

在第二步中,我通过使用另一个表中的数据(仅第一个查询尚未插入的产品,或者表中已不存在的产品)继续填充表格。

  INSERT    INTO COM_EXISTENCIAS
            (
              Mes ,
              Anyo ,
              Centro ,
              Stock ,
              Codigo
            )
            SELECT  @Mes ,
                    @Anyo ,
                    @Emp ,
                    0 ,
                    Cod_art
            FROM    COM_ENTRADAS
            WHERE   MONTH(Fecha) = @Mes
                    AND Emp = @Emp
                    AND YEAR(Fecha) = @Anyo
            EXCEPT
            SELECT  @Mes ,
                    @Anyo ,
                    @Emp ,
                    0 ,
                    Codigo
            FROM    COM_INVENTARIOS
            WHERE   Mes = @Mes
                    AND Centro = @Emp
                    AND Anyo = @Anyo
            EXCEPT
            SELECT  @Mes ,
                    @Anyo ,
                    @Emp ,
                    0 ,
                    Codigo
            FROM    COM_EXISTENCIAS
            WHERE   Mes = @Mes
                    AND Centro = @Emp
                    AND Anyo = @Anyo

只要我只需要运行一次,这就完美无缺。我的问题有时我需要重新运行存储过程,因为一些新产品已添加到COM_INVENTARIOS。我发现如果在第二步中已经从COM_ENTRADAS插入了一行并且现在存在于COM_INVENTARIOS中,而不是更新当前行,它会插入一个新行,所以我以两行具有相同数据结束。如果桌面上已经存在Mes,Centro,NumInv和Anyo,我应该如何修改查询的第一部分以进行更新而不是添加?

还有一个问题:在创建行之后,我再做一个额外的查询,在第三步中用COM_ENTRADAS中的数据更新它们。它现在有效,但是可能有一些更“干净”的方式来查询数据库,或者将两个查询连接在一起?

UPDATE  dbo.COM_EXISTENCIAS
SET     TotEntradas = T.TotEnt ,
        ImporteCompras = T.Importe
FROM    ( SELECT    Cod_art ,
                    ISNULL(ROUND(SUM(Cantidad), 3), 0) AS TotEnt ,
                    ISNULL(ROUND(SUM(( P_coste ) * ( Cantidad )), 2), 0) AS Importe
          FROM      COM_ENTRADAS
          WHERE     Emp = @Emp
                    AND MONTH(Fecha) = CAST(@Mes AS INT)
                    AND YEAR(Fecha) = CAST(@Anyo AS INT)
          GROUP BY  Cod_art
        ) AS T
WHERE   T.Cod_art = dbo.COM_EXISTENCIAS.Codigo
        AND Mes = @Mes
        AND Anyo = @Anyo
        AND Centro = @Emp

3 个答案:

答案 0 :(得分:0)

有一个很好的sql server子句叫MERGE,基本用法模式如下:

MERGE Table1 AS t
USING 
    (
        SELECT  field1,                           
                ...
        FROM Table2
    ) AS s
    ON t.field1 = s.field1
WHEN MATCHED THEN
    UPDATE 
    SET ...
WHEN NOT MATCHED THEN
    INSERT
        (                
            ...
        )
    VALUES
        (                
            ...
        );

因此,不是进行插入,而是在更新之后,您可以在单个SQL查询中完成所有操作

答案 1 :(得分:0)

这可能对你有帮助,,,

   IF EXISTS (SELECT 1 FROM dbo.COM_EXISTENCIAS WHERE Mes = @Mes ---Proceed your condition)
        BEGIN 
                ----YOUR UPDATE QUERY
        END
    ELSE
        BEGIN
            ---YOUR INSERT QUERY
        END

第二期

 IF EXISTS 
             (
                SELECT 1 FROM dbo.COM_EXISTENCIAS E INNER JOIN COM_INVENTARIOS I ON I.Codigo = E.Codigo WHERE E.Mes = @Mes and E.Centro=@Emp and E.Anyo=@Anyo 
            ) 

        BEGIN 
            UPDATE dbo.COM_EXISTENCIAS SET Stock = T.Stock 
                 FROM (
                       SELECT Codigo,Stock FROM COM_INVENTARIOS 
                       WHERE Centro=@Emp AND Mes=@Mes AND Anyo=@Anyo and NumInv = @NumInv
                       ) AS T 
                       WHERE T.Codigo=dbo.COM_EXISTENCIAS.Codigo AND Mes=@Mes AND Anyo=@Anyo AND Centro=@Emp 
        END ELSE 

答案 2 :(得分:0)

这就是我的查询现在的样子:

ALTER PROCEDURE [dbo].[COM_GRABA_EXISTENCIAS2] 

@Emp  nchar(3),@Mes nchar(2),@Anyo nchar(4),@MesAnt nchar(2),@NumInv int 
AS  
-- INSTRUCCION DE PRUEBA

 IF EXISTS (SELECT 1 FROM dbo.COM_EXISTENCIAS E INNER JOIN COM_INVENTARIOS I ON I.Codigo = E.Codigo WHERE E.Mes = @Mes and E.Centro=@Emp and E.Anyo=@Anyo) 
        BEGIN 
            UPDATE dbo.COM_EXISTENCIAS SET Stock = T.Stock 
                 FROM (
                       SELECT Codigo,Stock FROM COM_INVENTARIOS 
                       WHERE Centro=@Emp AND Mes=@Mes AND Anyo=@Anyo and NumInv = @NumInv
                       ) AS T 
                       WHERE T.Codigo=dbo.COM_EXISTENCIAS.Codigo AND Mes=@Mes AND Anyo=@Anyo AND Centro=@Emp 
        END 
    ELSE
        BEGIN
                    INSERT INTO COM_EXISTENCIAS (Mes,Anyo,Centro,Codigo,Stock,Descripcion)
                    SELECT I.Mes,I.Anyo,I.Centro,I.Codigo,SUM(I.Stock) as STOCK,I.Descripcion
                    FROM COM_INVENTARIOS I
                    WHERE I.Mes=@Mes and I.Centro=@Emp and I.NumInv = @NumInv
                    GROUP BY I.Codigo,I.Mes,I.Anyo,I.Centro,I.Descripcion
        END