Ora 06512/04088 вызывает ошибки, когда оператор INSERT INTO - PullRequest
2 голосов
/ 01 июня 2019

Я работаю над триггером, который предоставляет «домен» для столбца Molteplicità в таблице с именем Partecipa с использованием функции.

Триггер, который я создал, выглядит следующим образом:

CREATE OR REPLACE TRIGGER dominioMolteplicità
BEFORE INSERT OR UPDATE ON partecipa
FOR EACH ROW
BEGIN
    IF moltepl_valido(:NEW.molteplicità) = 'f' THEN
        RAISE_APPLICAZION_ERROR(-20002, 'Invalid type');
    END IF;
END;

, которая использует следующую функцию:

CREATE OR REPLACE FUNCTION motepl_valido(mol VARCHAR2) RETURN CHAR IS
BEGIN
    IF regexp_like(LOWER(mol), ' [*]\..[*] ') THEN
        RETURN 't';
    ELSE
        RETURN 'f';
    END IF;
END;

Таблица Partecipa имеет следующие столбцы:

CodP INT,
molteplicità VARCHAR2,
codAss INT,
className VARCHAR2,
PRIMARY KEY (codP),
FOREIGN KEY (className) REFERENCES class(name),
FOREIGN KEY (codAss) REFERENCES associazione(cod)`

, и хотя в моей таблице Associazione есть строки (в частности, codaAss: 42), а в моей таблице Class есть строки (в частности, className: 'Impiegato')

Когда я выполняю следующую инструкцию

insert into Partecipa(molteplicità, className, codAss) 
values ('*..*', 'Impiegato', 42);

Я получаю эти ошибки:

ORA-20002 НЕВЕРНЫЙ ТИП
ORA-06512: AT "dominioMolteplicità", строка 3
ORA-04088: ОШИБКА ПРИ ИСПОЛНЕНИИ ТРИГГЕРА "dominioMolteplicità"

(Обратите внимание, что если я отключу свой триггер, оператор вставки будет работать правильно. Есть некоторая проблема с триггером, но я не могу найти ошибку.)

Ответы [ 2 ]

2 голосов
/ 01 июня 2019

Это не связано с триггером.

Ваша функция motepl_valido повышает ORA-20002 INVALID TYPE, если предоставленная строка (в данном случае '*..*') не соответствует регулярному выражению ' [*]\..[*] '. Он не совпадает, потому что в нем отсутствуют необходимые пробелы.

Демонстрация, демонстрирующая эффект выбора шаблонов регулярных выражений (я добавил | вокруг шаблонов, чтобы показать начальные и конечные пробелы):

with demo (molteplicita) as
     ( select '*..*' from dual union all
       select ' *..* ' from dual union all
       select ' *x.* ' from dual )
   , patterns (pattern) as
     ( select '[*]\..[*]' from dual union all
       select ' [*]\..[*] ' from dual union all
       select ' *[*]\..[*] *' from dual union all
       select ' *\*\..\* *' from dual )
select '|'||pattern||'|' as pattern
     , '|'||molteplicita||'|' as molteplicita
     , case when regexp_like(molteplicita, pattern) then 'Yes' else 'No' end as matched
from   demo cross join patterns
order by pattern, molteplicita desc;

PATTERN          MOLTEPLICITA MATCHED
---------------- ------------ -------
| *[*]\..[*] *|  |*..*|       Yes
| *[*]\..[*] *|  | *x.* |     No
| *[*]\..[*] *|  | *..* |     Yes

| *\*\..\* *|    |*..*|       Yes
| *\*\..\* *|    | *x.* |     No
| *\*\..\* *|    | *..* |     Yes

| [*]\..[*] |    |*..*|       No
| [*]\..[*] |    | *x.* |     No
| [*]\..[*] |    | *..* |     Yes

|[*]\..[*]|      |*..*|       Yes
|[*]\..[*]|      | *x.* |     No
|[*]\..[*]|      | *..* |     Yes


12 rows selected.
1 голос
/ 01 июня 2019

Поскольку ваш шаблон не соответствует вашим данным

Полагаю, regexp_like( lower(mol), '\*..\*') будет в порядке, и в этом случае будут работать такие значения, как '*=-*' или '*34*' для molteplicità.

Кстати, даже используя '[\*]..[\*]' (, где обратный слеш используется в качестве escape-символа ) в качестве шаблона, возможно, будет возможно для приведенного выше регулярного выражения.

Демонстрация:

with t( mol ) as
(
 select '*24*' from dual union all
 select 'B' from dual union all
 select '*=-*' from dual 
)
select 
  case when regexp_like(lower(mol), '\*..\*') then 't' else 'f' end suggested_pattern1,
  case when regexp_like(lower(mol), '[\*]..[\*]') then 't' else 'f' end suggested_pattern2,
  case when regexp_like(lower(mol), '[*]\..[*]') then 't' else 'f' end original_pattern,
  case when regexp_like(lower(mol), '*..*') then 't' else 'f' end anticipated_pattern
  from t;

SUGGESTED_PATTERN1  SUGGESTED_PATTERN2  ORIGINAL_PATTERN  ANTICIPATED_PATTERN
t                   t                   f                 t
f                   f                   f                 t
t                   t                   f                 t

PS Обратите внимание, что anticipated_pattern также не будет работать (для mol = 'B' в приведенном выше примере).

...