Таблица UPDATE / INSERT для нескольких циклов для выбранных строк с условиями WHERE - PullRequest
0 голосов
/ 17 мая 2019

У меня есть две таблицы, подобные этой:

Table1

DataS DataH DataO
001    101    ABA
003    101    ABC
001    101    AAB
001    105    BBA
002    102    ABB
002    102    ACA

Table2

DataS DataH DataO Result1 Result2 Result3
003   101   ABC
001   105   BBA

Я пытаюсь сделать процедуру с двумя входными параметрами: @DataS, @DataH. Какую процедуру следует сделать:

  1. Выбрать все записи из таблицы1 WHERE DataS=@DataS AND DataH=@DataH.
  2. Для каждой выбранной строки проверьте, существует ли запись IF в таблице 2 с теми же тремя значениями [DataS] [DataH] [DataO].
  3. ЕСЛИ да - ОБНОВИТЬ эту строку в таблице 2 (SET Result1 = (MyFunction), SET Result2 = (MyFunction) и т. Д.)
  4. IF no - ВСТАВИТЬ эту строку со всеми параметрами [DataS] [DataH] [DataO] [Result1] [Result2] [Result3]

Поэтому после выполнения процедуры таблица 2 должна выглядеть следующим образом:

Таблица2 (после обновления)

DataS  DataH DataO Result1 Result2 Result3
003    101   ABC   1.5     1.3     1.4
001    105   BBA   1.6     1.1     1.3
001    101   ABA   1.6     1.3     1.4
001    101   AAB   1.6     1.3     1.4
002    102   ABB   1.1     1.4     1.4
002    102   ACA   1.3     1.4     1.1

Возможно ли сделать это за одну процедуру? Каков наилучший способ (сохранить также хорошую эффективность)? Можно ли сделать это с помощью cte или есть лучшее решение, какая-нибудь функция цикла?

DECLARE @ID int
SELECT @ID = (SELECT ID FROM Table2 WHERE DataS=@DataS AND DataH=@DataH AND DataO=@DataO)
IF EXISTS @ID
BEGIN
    --UPDATE Table2 SET Result1=... WHERE ID=@ID
END
ELSE
BEGIN
   --INSERT INTO Table2 (.....)
END

UPDATE: Я думаю, что лучшее решение - использовать MERGE, как сказал Луис Казарес (спасибо), поэтому я сделал новую процедуру, такую ​​как:

MERGE Table2 AS ex
USING x AS st
ON (x.DataS = st.DataSAND ex.DataO = st.DataO AND ex.DataH = st.DataH)
WHEN MATCHED THEN UPDATE SET ex.Result1 = 9
WHEN NOT MATCHED THEN
INSERT(DataS,DataH,DataO,Result1)
VALUES(st.DataS,st.DataH,st.DataO,9);

Выглядит так умно, но это не работает, и я заметил, что MERGE не поддерживается на старом SQL Server 2005, который я использую (начиная с 2008 года). Поэтому я пытаюсь использовать функцию CURSOR, как предложил mkRabbani, и она работает (спасибо).

1 Ответ

0 голосов
/ 17 мая 2019

Это может быть достигнуто с помощью CURSOR, как определено ниже. Тестовые значения должны быть заменены на выходные данные вашей функции.

DECLARE @DataS VARCHAR(50)
DECLARE @DataH VARCHAR(50)

SET @DataS  =  '003'
SET @DataH = '101'

DECLARE @DataS_T1 VARCHAR(50)
DECLARE @DataH_T1 VARCHAR(50)
DECLARE @DataO_T1 VARCHAR(50)
DECLARE @DataS_T2 VARCHAR(50)
DECLARE @DataH_T2 VARCHAR(50)
DECLARE @DataO_T2 VARCHAR(50)

DECLARE db_cursor CURSOR 
FOR 
SELECT 
T1.DataH DataH_T1,T1.DataO DataO_T1,T1.DataS DataS_T1,
T2.DataH DataH_T2,T2.DataO DataO_T2,T2.DataS DataS_T2  
FROM Table1 T1
LEFT JOIN Table2 T2
    ON T1.DataH = T2.DataH AND T1.DataO =T2.DataO AND T1.DataS = T2.DataS
WHERE T1.DataH = @DataH
AND T1.DataS = @DataS

OPEN db_cursor  
FETCH NEXT FROM db_cursor INTO @DataH_T1,@DataO_T1,@DataS_T1,@DataH_T2,@DataO_T2,@DataS_T2  

WHILE @@FETCH_STATUS = 0  
BEGIN  

      IF (@DataH_T2 IS NULL)
      BEGIN
          INSERT INTO Table2 (DataS,DataH,DataO,Result1,Result2,Result3)
          VALUES (@DataS_T1,@DataH_T1,@DataO_T1,'Test Result 1','Test Result 2','Test Result 3')
      END

      ELSE
      BEGIN
          UPDATE Table2
          SET Result1 = 'Test',
          Result2= 'test2',
          Result3= 'Test3'
          WHERE DataS = @DataS_T2 
          AND DataH = @DataH_T2
          AND DataO = @DataO_T2
      END

      FETCH NEXT FROM db_cursor INTO @DataH_T1,@DataO_T1,@DataS_T1,@DataH_T2,@DataO_T2,@DataS_T2  
END 

CLOSE db_cursor  
DEALLOCATE db_cursor
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...