Дополнительное задание 5.12
Постановка задачи
В таблицу Специальность добавить столбец Шифр_Специальности
. Создать Compound-триггер, который при внесении или изменении названия специальности, будет вводить в соответствующую ячейку столбца Шифр_Специальности
первые буквы каждого слова в названии специальности. Проверьте работу триггера при одновременном изменении нескольких записей одной командой UPDATE
и одновременном внесении нескольких строк командой INSERT..SELECT
.
Решение
Добавим столбец Шифр_Специальности
:
ALTER TABLE Специальности ADD (Шифр_Специальности VARCHAR2(40));
SELECT * FROM Специальности;
КОД_СПЕЦИАЛЬНОСТИ | НАЗВАНИЕ_СПЕЦИАЛЬНОСТИ | ШИФР_СПЕЦИАЛЬНОСТИ |
---|---|---|
1 | СИСТЕМЫ АВТОМАТИЧЕСКОГО УПРАВЛЕНИЯ | (null) |
2 | МАТЕМАТИЧЕСКОЕ ОБЕСПЕЧЕНИЕ ЭВМ | (null) |
3 | ВЫЧИСЛИТЕЛЬНЫЕ СЕТИ И СИСТЕМЫ | (null) |
4 | ЭКОНОМИКА ПРЕДПРИЯТИЙ | (null) |
Создадим триггер:
CREATE OR REPLACE TRIGGER Шифр_Специальности_Trg
FOR INSERT OR UPDATE OF Название_Специальности ON Специальности
COMPOUND TRIGGER
FUNCTION getCipher (specName Специальности.Название_Специальности%TYPE)
RETURN Специальности.Шифр_Специальности%TYPE IS
word_re VARCHAR2(256) := '[[:alpha:]]([-''_[:alpha:][:digit:]]*[''[:alpha:][:digit:]])?';
letters VARCHAR2(1024) := '';
word VARCHAR2(1024);
BEGIN
IF specName IS NULL THEN RETURN NULL; END IF;
FOR i IN 1..REGEXP_COUNT(specName, word_re) LOOP
word := REGEXP_SUBSTR(specName, word_re, 1, i);
letters := letters || REGEXP_SUBSTR(word, '[[:alpha:]]', 1, 1);
END LOOP;
RETURN letters;
END;
BEFORE EACH ROW IS
BEGIN
-- Меняем Шифр_Специальности только если фактические значения
-- столбцов Название_Специальности различаются
IF UPDATING AND NOT (
:OLD.Название_Специальности IS NULL AND :NEW.Название_Специальности IS NULL
) AND (
:OLD.Название_Специальности IS NULL OR :NEW.Название_Специальности IS NULL
OR :OLD.Название_Специальности != :NEW.Название_Специальности
)
THEN
:NEW.Шифр_Специальности := getCipher(:NEW.Название_Специальности);
END IF;
IF INSERTING THEN
:NEW.Шифр_Специальности := getCipher(:NEW.Название_Специальности);
END IF;
END BEFORE EACH ROW;
END Шифр_Специальности_Trg;
/
Результат
Добавим 3 строки:
INSERT INTO Специальности (Код_Специальности, Название_Специальности)
SELECT 5, 'Программная инженерия' FROM dual
UNION ALL SELECT 6, 'Психолого-педагогическое образование' FROM dual
UNION ALL SELECT 7, 'Ядерные физика и технологии' FROM dual;
SELECT * FROM Специальности
ORDER BY Код_Специальности;
КОД_СПЕЦИАЛЬНОСТИ | НАЗВАНИЕ_СПЕЦИАЛЬНОСТИ | ШИФР_СПЕЦИАЛЬНОСТИ |
---|---|---|
1 | СИСТЕМЫ АВТОМАТИЧЕСКОГО УПРАВЛЕНИЯ | (null) |
2 | МАТЕМАТИЧЕСКОЕ ОБЕСПЕЧЕНИЕ ЭВМ | (null) |
3 | ВЫЧИСЛИТЕЛЬНЫЕ СЕТИ И СИСТЕМЫ | (null) |
4 | ЭКОНОМИКА ПРЕДПРИЯТИЙ | (null) |
5 | Программная инженерия | Пи |
6 | Психолого-педагогическое образование | По |
7 | Ядерные физика и технологии | Яфит |
Заметим, что специальность «Психолого-педагогическое образование» получила шифр «По», т.к. «психолого-педагогическое» — одно слово в русском языке. Строки, которые были в таблице до INSERT
'а не получили новый шифр, т.к. соответствующие фактические значения названий специальностей не изменились.
Обновим все строки таблицы:
UPDATE Специальности
SET Название_Специальности = LOWER(Название_Специальности);
SELECT * FROM Специальности
ORDER BY Код_Специальности;
КОД_СПЕЦИАЛЬНОСТИ | НАЗВАНИЕ_СПЕЦИАЛЬНОСТИ | ШИФР_СПЕЦИАЛЬНОСТИ |
---|---|---|
1 | системы автоматического управления | сау |
2 | математическое обеспечение эвм | моэ |
3 | вычислительные сети и системы | всис |
4 | экономика предприятий | эп |
5 | программная инженерия | пи |
6 | психолого-педагогическое образование | по |
7 | ядерные физика и технологии | яфит |