2015-02-06 2 views
0

У меня следующий UPDATE заявлениеОбновление нескольких столбцов с помощью оператора выбора же SQL сервера

UPDATE PAYMENT_HISTORY 
SET request_status_id = 
CASE 
    WHEN PHP.request_status_id = PHP.prevRequest_status_id THEN NULL 
    ELSE PHP.request_status_id 
END, 
    is_changed = 
CASE 
    WHEN PHP.request_status_id = PHP.prevRequest_status_id THEN 0 
    ELSE 1 
END  

Можно ли обновить обе колонки с помощью одного оператора случай?

+0

Я считаю, что вам нужно скопировать-вставить аргумент case-when несколько раз – abatishchev

+0

Проблема только в псевдониме PHP? Работает ли он, если вы его оставите? –

+0

@JamesZ мне не нужны эти псевдонимы ... там некоторые основные JOINS –

ответ

1

В принципе это невозможно. Вы можете перемещать CASE..END функционировать и называть это так, но влияние discutable ...

UPDATE PAYMENT_HISTORY 
SET 
    request_status_id = dbo.fnCalc(PHP.request_status_id, PHP.prevRequest_status_id, 1), 
    is_changed = dbo.fnCalc(PHP.request_status_id, PHP.prevRequest_status_id, 2) 
1

Пожалуйста, обратитесь к BOL для пункта обновления: https://msdn.microsoft.com/en-us/library/ms177523.aspx

В частности column_name = { expression | DEFAULT | NULL }

Выражения разрешены только с правой стороны, поэтому вы не можете написать выражение, чтобы выбрать, какой столбец обновиться.

1

Или если логика настолько проста, вы можете сделать это, используя 2 обновления, второе обновление основано на результате первого обновления. Но опять же, у вас есть причина сделать это таким образом.

UPDATE PAYMENT_HISTORY 
    SET request_status_id = 
    CASE 
    WHEN PHP.request_status_id = PHP.prevRequest_status_id THEN NULL 
    ELSE PHP.request_status_id 
    END 

UPDATE PAYMENT_HISTORY SET 
    is_changed = 
    CASE 
     WHEN request_status_id is NULL THEN 0 
     ELSE 1 
    END  

ИЛИ более эффективного выполнения (второе обновление будет обновлять только те строки, которые должны быть обновлены)

UPDATE PAYMENT_HISTORY 
    SET 
    request_status_id = 
    CASE 
     WHEN PHP.request_status_id = PHP.prevRequest_status_id THEN NULL 
     ELSE PHP.request_status_id 
    END, 
    is_changed=0 


UPDATE PAYMENT_HISTORY SET 
    is_changed = 1 
    WHERE 
    request_status_id is not NULL 
2

Можно ли обновить обе колонки с помощью одного оператора случай?

Номер A CASE выражение имеет одно атомное значение. Одно выражение CASE не может иметь значение двух полей. Вы не можете установить как request_status_id, так и is_changed при одном использовании CASE ... END.

Можно обновить оба поля в одном и том же заявлении UPDATE, но не то же самое выражение CASE.

Однако ваше выражение не проблематично, и ваши задания здесь не будут наступать друг на друга. Данные, которые читаются, блокируются, когда инструкция начинает выполняться. Он использует таблицу, как она существовала до запуска оператора.

Рассмотрим:

CREATE TABLE TestTable (
    Odd TINYINT NOT NULL, 
    Even TINYINT NOT NULL, 
    PRIMARY KEY (Odd, Even) 
); 

INSERT INTO TestTable (Odd, Even) VALUES (1, 2); 
INSERT INTO TestTable (Odd, Even) VALUES (3, 4); 
INSERT INTO TestTable (Odd, Even) VALUES (5, 6); 
INSERT INTO TestTable (Odd, Even) VALUES (7, 8); 

SELECT * FROM TestTable; 

UPDATE TestTable SET Odd = Even, Even = Odd; 

SELECT * FROM TestTable; 

SQLFiddle

Если вы делаете что-то странное, как рекурсивный КТР, данные в значительной степени установить, как они были до выполнения инструкции.

0

Да, это возможно при использовании переменной.

UPDATE PAYMENT_HISTORY 
SET request_status_id = 
CASE 
    WHEN PHP.request_status_id = PHP.prevRequest_status_id 
    THEN coalesce((@ischanged:=0)+null,NULL) 
    ELSE coalesce((@ischanged:=1)+null,PHP.request_status_id) 
    END, 
    is_changed = @ischanged 

В целом:

UPDATE mytable 
SET 
    a = CASE 
    WHEN [condition1] 
     THEN coalesce((@b:= [b expression]) +null, (@c:= [c expression]) +null, [a expression]) 
    WHEN [condition2] 
     THEN coalesce((@b:= [b expression]) +null, (@c:= [c expression]) +null, [a expression]) 
    ELSE coalesce((@b:= [b expression]) +null, (@c:= [c expression]) +null, [a expression]) 
    END, 
    b = @b, 
    c = @c 

Дозапись для каждого входного параметра в COALESCE «+ нуль», чтобы гарантировать, что выражение выполняется и результат сохраняется в переменной, но результат выражения не возвращается функцией коалесценции.

Протестировано на MySQL.

Смежные вопросы