#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’)»