Oracle Триггер: ведение связанных экземпляров таблиц в новой INSERT на основе информации в третьей таблице (каталог) - PullRequest
0 голосов
/ 28 апреля 2020

Я пытаюсь автоматизировать создание экземпляров датчиков в таблице при вставке нового инструмента в другую таблицу в Oracle.

Датчик относится к «инструменту», а «каталог» говорит, что «этот тип инструмента» должен иметь х датчиков, описанных в таблице SENSORS_CATALOG.

Чтобы прояснить ситуацию, вот (очень упрощенная) конфигурация таблицы:

SENSORS_CATALOG : 

| S_CATAL_ID | NAME | INSTR_CATAL_ID |
--------------------------------------
|        5   | FOO1 |            99  |
|        6   | BAR1 |            99  |
|       11   | FOO2 |           100  |
|       12   | BAR2 |           100  |


INSTRUMENTS : 

| INSTR_ID | SERIAL | INSTR_CATAL_ID |
--------------------------------------
|       51 | ABC    |             99 |


SENSORS : 

| SENSOR_ID | S_CATAL_ID | INSTR_ID |
-------------------------------------
|         1 |          5 |       51 |
|         2 |          6 |       51 |

До сих пор эта таблица SENSORS поддерживается в soft. ... что опасно. Я хотел бы вызвать экземпляр SENSORS на INSTRUMENT insert.

У всех этих таблиц уже есть триггер для заполнения и генерирования их первичного ключа ID из последовательности (сначала столбец).

Моя трудность здесь заключается в том, чтобы получить новый идентификатор, а затем вставить в другую таблицу на основе третьей ... Я думаю, что я довольно близок с этим (но все равно будет иметь проблема вставки вновь созданного идентификатора в таблицу SENSORS, см. комментарий):

TRIGGER TRG_NAME
BEFORE INSERT OR UPDATE ON INSTRUMENTS
FOR EACH ROW

DECLARE
  sensor_in_catal_numb NUMBER;  -- number of sensors this instrument should have
  sensor_numb NUMBER;           -- number of sensors found already declared for this instrument id

BEGIN

   -- autoincrement section (get a new ID from sequence if none provided)
   if inserting then 
      if :NEW."INSTR_ID" is null then 
         select INSTRUMENT_SEQ.nextval into :NEW."INSTR_ID" from dual; 
      end if; 
   end if; 

  -- find number of sensors this instrument should have
  SELECT COUNT(S_CATAL_ID) INTO sensor_in_catal_numb
  FROM SENSORS_CATALOG
  WHERE SENSORS_CATALOG.INSTR_CATAL_ID = :NEW.INSTR_CATAL_ID;

  -- find the number of sensors instances this instrument already has
  SELECT COUNT(SENSOR_ID) INTO sensor_in_catal_numb
  FROM SENSORS
  WHERE SENSORS.INSTR_ID = :NEW.INSTR_ID;

  -- if no sensor instantiated, do it
  IF sensor_numb == 0 THEN

    INSERT INTO SENSORS(S_CATAL_ID, INSTR_ID)
    SELECT S_CATAL_ID, :NEW.INSTR_ID as INSTR_ID  -- PROBLEM HERE : ":NEW.INSTR_ID" is not a constant (or is it?)!
    FROM SENSORS_CATALOG 
    WHERE SENSORS_CATALOG.INSTR_CATAL_ID = :NEW.INSTR_CATAL_ID

  -- if sensors instantiated but improperly... raise error (small test, not checking proper values)
  ELSIF sensor_num != sensor_in_catal_numb THEN

    RAISE_APPLICATION_ERROR(-20110, 'Consistency error : INSTR_ID ('|| :NEW.INSTR_ID ||') already has' || sensor_numb || ' declared while it should have '|| sensor_in_catal_numb || '.');

  END IF;

END;

Когда вставлена ​​новая строка в INSTRUMENTS (instr_id = 52, instr_catal_id = 100), соответствующие датчики в таблица SENSORS создается, и таблица должна стать:

SENSORS : 

| SENSOR_ID | S_CATAL_ID | INSTR_ID |
-------------------------------------
|         1 |          5 |       51 |
|         2 |          6 |       51 |
|         3 |         11 |       52 |
|         4 |         12 |       52 |

Есть идеи, как ее правильно написать? Любые комментарии по поводу стиля / метода кода приветствуются (я новичок ie, на случай, если это не было очевидно ^^).

...