2014-02-20 4 views
0

Мне нужна помощь в этой хранимой процедуре SQL. Я собираю промежуточную таблицу (COM_EXISTENCIAS) с источниками из разных таблиц для целей отчетности. На первом этапе я заполнить его с данными в COM_INVENTARIOS таблице, которые соответствуют определенным реквизитам, сгруппированные подвести запасы, если есть больше, чем линии, совпадающих с cryteria:SQL: обновление, если существует с хранимой процедурой

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 
+0

Вы можете '' UPDATE' или INSERT' в соответствии с условиями с 'п MERGE': msdn.microsoft.com/en-us /library/bb510625.aspx – NickyvV

+0

Забыл сказать, что это SQL 2005, поэтому я не могу использовать MERGE, к сожалению. – user3328998

ответ

0

Ну есть пункт хороший сервер SQL называется 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

+0

MERGE его нет для SQL2005, боюсь. – user3328998

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 [email protected] and [email protected] 
      ) 

     BEGIN 
      UPDATE dbo.COM_EXISTENCIAS SET Stock = T.Stock 
       FROM (
         SELECT Codigo,Stock FROM COM_INVENTARIOS 
         WHERE [email protected] AND [email protected] AND [email protected] and NumInv = @NumInv 
         ) AS T 
         WHERE T.Codigo=dbo.COM_EXISTENCIAS.Codigo AND [email protected] AND [email protected] AND [email protected] 
     END ELSE 
+0

Спасибо, суреш. Я изменил хранимую процедуру: она отлично работала при первом выполнении (она занесла нужные регистры). Однако это не сработало, как предполагалось, во втором исполнении (он не запустил новую строку, но не обновил текущий). Я предполагаю, что это связано с тем, что в запросе SELECT 1 не используется поле «codigo» (поле для кода продукта). Во всяком случае, я не знаю точно, как вызвать Codigo там, поэтому он обновляет только строки, присутствующие в COM_INVENTARIOS. – user3328998

+0

Вот как это выглядит моя процедура в настоящее время: IF EXISTS (SELECT 1 FROM dbo.COM_EXISTENCIAS WHERE Mes = @Mes и Centro = @ Emp и Anyo = @ Anyo) НАЧАТЬ \t UPDATE dbo.COM_EXISTENCIAS \t \t \t \t SET Stock = T.Фото \t \t \t \t ИЗ \t \t \t \t \t (SELECT Codigo, Шток \t \t \t \t \t ИЗ COM_INVENTARIOS \t \t \t \t \t WHERE Centro = @ Emp И Mes = @ Mes И Anyo = @ Anyo и NumInv = @NumInv) \t \t \t \t AS T WHERE T.Codigo = dbo.COM_EXISTENCIAS.Codigo AND Mes = @ Mes AND Anyo = @ Anyo AND Centro = @ Emp END ELSE – user3328998

+0

Можете ли вы опубликовать свою точную хранимую процедуру для ясного понимания ???? – sureshhh

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 [email protected] and [email protected]) 
     BEGIN 
      UPDATE dbo.COM_EXISTENCIAS SET Stock = T.Stock 
       FROM (
         SELECT Codigo,Stock FROM COM_INVENTARIOS 
         WHERE [email protected] AND [email protected] AND [email protected] and NumInv = @NumInv 
         ) AS T 
         WHERE T.Codigo=dbo.COM_EXISTENCIAS.Codigo AND [email protected] AND [email protected] AND [email protected] 
     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 [email protected] and [email protected] and I.NumInv = @NumInv 
        GROUP BY I.Codigo,I.Mes,I.Anyo,I.Centro,I.Descripcion 
     END 
Смежные вопросы