как разделить установленные значения и вставить каждую строку в Trigger PL / SQL?

#mysql #plsql #triggers

#mysql #plsql #триггеры

Вопрос:

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

вопрос:

значение идентификатора
1 2,5,8

ответ:

значение идентификатора
1 2
1 5
1 8

Комментарии:

1. Немного запутанный вопрос. Вы хотите сделать «вставить в значения my_table (1, ‘2,5,8’)» и получить логику типа «вставить в значения my_table (1, ‘2’); вставить в значения my_table (1, ‘5’); вставить в значения my_table (1, ‘8’)»?

2. да. я хочу это, но с использованием триггеров.

Ответ №1:

Триггеры в Oracle имеют режим «ВМЕСТО», что именно то, что вам нужно, но проблема в том, что вы не можете использовать триггер «ВМЕСТО» в простой таблице, он доступен только для представлений. Итак, единственный вариант, который я вижу для вас, — это обернуть вашу таблицу в представление. Например, у вас есть таблица:

 create table my_table(c_id number, c_value varchar2(5))
  

Переименуйте его и создайте представление со старым именем таблицы:

 rename my_table to my_table_old;

create view my_table as select * from my_table_old;
  

Все существующие запросы к my_table должны работать с этим представлением, включая обновления и удаления. Теперь мы можем создать ВМЕСТО триггера:

 create or replace trigger t_my_table
instead of insert on my_table
for each row
declare
  qid number;
begin
  insert into my_table_old
  select :new.c_id, regexp_substr (:new.c_value, '[^,] ', 1, level) as part
  from dual  
  connect by level <= length (regexp_replace (:new.c_value, '[^,] '))    1;
end;
  

Этот иерархический запрос превратит строку, разделенную запятыми, в таблицу с единственным значением в строке.

Хорошо, давайте проверим, работает ли это:

 SQL> insert into my_table values (1, '2,5,8');

1 row created.

SQL> select * from my_table;

      C_ID C_VALUE
---------- ---------------
         1 2
         1 5
         1 8
  

Простая вставка с одним значением также будет работать:

 SQL> insert into my_table values (2, '100');

1 row created.

SQL> select * from my_table;

      C_ID C_VALUE
---------- ---------------
         1 2
         1 5
         1 8
         2 100
  

Обратите внимание, что использование триггера немного повлияет на производительность запросов на вставку.

Комментарии:

1. я получил эту ошибку. # 1064 — У вас ошибка в вашем синтаксисе SQL; проверьте руководство, соответствующее вашей версии сервера MySQL, на предмет правильного синтаксиса для использования рядом с ‘trigger t_my_table вместо insert в my_table для объявления qid каждой строки для каждой строки ‘ в строке 1

2. С oracle тегом в вашем вопросе вы должны ожидать oracle ответов. 😉

3. Извините, не знаю о триггерах в MySQL.

Ответ №2:

Вы можете изменить регулярное выражение в соответствии с вашими точными требованиями, но следующее эффективно выполняется в соответствии с вашим вопросом:

 CREATE OR REPLACE TRIGGER XX_ORDER_TRG 
BEFORE INSERT ON XX_ORDER_TBL
FOR EACH ROW
DECLARE 

l_num1 NUMBER;
l_num2 NUMBER;
l_num3 NUMBER;

BEGIN

/* If the whole string in value matches 3 single digits separated by commas */
IF  REGEXP_LIKE(:new.value,'^(d{1},d{1},d{1})$') THEN
    /* Split the value into its 3 separate digits - Capture Groups are not supported natively*/
    l_num1 := REGEXP_SUBSTR(:new.value,'d{1}',1,1);
    l_num2 := REGEXP_SUBSTR(:new.value,'d{1}',1,2);
    l_num3 := REGEXP_SUBSTR(:new.value,'d{1}',1,3);

    :new.value := l_num1;
    INSERT INTO XX_TBL (id, value) VALUES (:new.id, l_num2);
    INSERT INTO XX_TBL (id, value) VALUES (:new.id, l_num3);

END IF;           


END;
  

Комментарии:

1. ВСТАВЬТЕ В значения my_table (1, ‘2,5,8’) и получите ТРИГГЕРЫ, вставляющие логику типа «вставить в значения my_table (1, ‘2’); вставить в значения my_table (1, ‘5’); вставить в значения my_table (1, ‘8’)»