2016-10-13 4 views
0

Я пытаюсь обновить поле текущей вставленной строки в AS400. Я использую версии 4.5, 5.3 и 7.1.Update Trigger on Insert in AS400

Для моих тестов я создал таблицу WC (рабочий центр), содержащую поле CRTDT (NUMERIC 7,0) При вставке новой записи в эту таблицу, я хочу проверить, меньше ли значение этого поля что 200 000, и если да, добавьте к нему 1 000 000.

Мой SQL является:

-- Generate SQL 
-- Version:     V5R4M0 060210 
-- Generated on:    10/13/16 10:03:49 
-- Relational Database:  S65BEE7B 
-- Standards Option:   DB2 UDB iSeries 
CREATE TRIGGER RAVONLIB.WC_TRIGGER 
    AFTER INSERT ON RAVONLIB.WC 
    FOR EACH STATEMENT 
    MODE DB2SQL 
    SET OPTION ALWBLK = *ALLREAD , 
    ALWCPYDTA = *OPTIMIZE , 
    COMMIT = *NONE , 
    DECRESULT = (31, 31, 00) , 
    DFTRDBCOL = *NONE , 
    DYNDFTCOL = *NO , 
    DYNUSRPRF = *USER , 
    SRTSEQ = *HEX 
    BEGIN ATOMIC 
IF WC.CRTDT<200000 THEN 
    UPDATE RAVONLIB . WC SET CRTDT = 1000000 + CRTDT ; 
END IF; 
END ; 

Я получаю сообщение об ошибке, что переменная CRTDT не определена или не годных к употреблению. Каков правильный синтаксис для правильного обновления CRTDT, если он меньше 200000?

+0

Является ли это DB2 или другим dbms? – jarlh

+0

Да, это IBM DB2 – ehh

+0

Есть ли причина, по которой вы хотите сделать UPDATE для WC таблицы в ** После ** Обновить триггер на WC таблицы? – user2338816

ответ

4

Вы должны использовать триггер BEFORE INSERT.

Кроме того, вам необходимо изменить значение столбца, поскольку оно вставлено ... вы не можете запустить инструкцию SQL UPDATE в триггере в строке, которая только что была вставлена.

Наконец, вам нужен триггер строки, а не триггер инструкции.

CREATE TRIGGER RAVONLIB.WC_TRIGGER 
    BEFORE INSERT ON RAVONLIB.WC 
    REFERENCING NEW AS new_row 
    FOR EACH ROW MODE DB2ROW 
    SET OPTION ALWBLK = *ALLREAD , 
    ALWCPYDTA = *OPTIMIZE , 
    COMMIT = *NONE , 
    DECRESULT = (31, 31, 00) , 
    DFTRDBCOL = *NONE , 
    DYNDFTCOL = *NO , 
    DYNUSRPRF = *USER , 
    SRTSEQ = *HEX 
    BEGIN ATOMIC 
IF new_row.CRTDT<200000 THEN 
    SET new_row.CRTDT = 1000000 + new_row.CRTDT ; 
END IF; 
END ; 
+0

Я нашел синтаксическое решение для после вставки, но ваше решение еще лучше и логично.Спасибо – ehh

+1

FWiW: Оператор UPDATE * может * запускаться только по вставленной строке [из триггера AFTER INSERT], а триггер FOR EACH STARTEMENT * может быть более желательным [и быть определенным для того, чтобы использовать UPDATE с использованием перехода табличные данные], чем триггер FOR EACH ROW; что я согласен с ***, если *** применим ко всем: • с использованием триггера BEFORE INSERT • с помощью инструкции SET для обновления конкретного входящего значения в триггере BEFORE INSERT • [таким образом] с использованием триггера ROW – CRPence

1

FWIW, в основном назидание, так как это вряд ли ответ дали свой комментарий к уже принятому ответу: Как проверяются на V5R3, подражает заявления триггерных от OP к логическому вывод; не знаю, кто бы даже имел систему v4r5, на которой нужно было протестировать - ¡святой дым!:

create table wc 
(PKfld int not null 
, CRTDT numeric(7) 
, constraint WC_PK primary key (PKfld) 
)    
; 
CREATE TRIGGER wc_trg_ai      
After Insert on WC        
REFERENCING NEW TABLE AS xt      
FOR EACH STATEMENT MODE DB2SQL     
SET OPTION COMMIT = *NONE      
    BEGIN ATOMIC         
    update WC set WC.CRTDT = WC.CRTDT + 1000000 
    where WC.CRTDT<200000      
    and exists (select '1' from XT as xt  
        where xt.PKfld = WC.PKfld) ; 
    END           
; -- semicolon as statement separator, not end of trigger-body 
insert into wc values         
    ( 1, '0000001'), ( 2, '0200000'), ( 3, '0000300') 
, ( 4, '0400000'), ( 5, '0050000'), ( 6, '0600000') 
; -- per trigger dfn, the even-numbered key values will not see an UPDATE 
select * from WC 
; -- likeness of report from above query: 
    PKFLD  CRTDT 
     1 1,000,001 
     2  200,000 
     3 1,000,300 
     4  400,000 
     5 1,050,000 
     6  600,000 
*** End of data *** 
+0

Не совсем понятно, почему вам пришлось ссылаться на xt и почему это новая таблица. Upvoted, поскольку он отлично подходит для меня тоже – ehh

+0

XT представляет таблицу перехода с копией всех затронутых строк для вставки SQL, к которой должен обращаться SQL-триггер, чтобы узнать, каковы фактические записи в WC, которые необходимо быть объектом заявления UPDATE; то, что показано, является ПОСЛЕ ВСТАВКИ, поэтому данные уже были вставлены в WC, а оператор UPDATE должен обновлять только те строки, которые были вставлены в оператор INSERT. Если логика WHERE EXISTS удалена, действие будет обновлять больше данных, чем то, что было вставлено; возможно, отлично подходит для этого конкретного сценария, но этот эффект обычно рассматривается как * коррупция *. – CRPence

+0

Очень ясно, спасибо за отличное объяснение – ehh