Ora 06512/04088 INSERT INTO 语句时触发错误

Ora 06512/04088 triggers errors when INSERT INTO statement

我正在为一个触发器工作,它使用一个函数为名为 Partecipa 的 table 中的列 Molteplicità 提供 "domain"。

我创建的触发器如下:

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;

Table 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 table 中有行(特别是 codaAss: 42)并且在我的 Class table 中有行(特别是 className : 'Impiegato')

当我执行下面的语句时

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

我收到这些错误:

ORA-20002 INVALID TYPE
ORA-06512: AT "dominioMolteplicità", line 3
ORA-04088: ERROR DURING EXECUTION OF TRIGGER "dominioMolteplicità"

(请注意,如果我禁用我的触发器,插入语句会正常工作。触发器有一些问题,但我找不到错误。)

因为你的模式不符合你的数据

我想 regexp_like( lower(mol), '\*..\*') 没问题,在这种情况下,诸如 '*=-*''*34*' 之类的值适用于 molteplicità。

顺便说一句,即使使用 '[\*]..[\*]' 其中反斜杠用作转义字符)作为上述正则表达式的模式也是可能的。

演示:

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

P.S。请注意 anticipated_pattern 也会失败(对于上述示例中的 mol = 'B')。

与触发器无关

如果提供的字符串(在本例中为 '*..*')与正则表达式 ' [*]\..[*] ' 不匹配,您的函数 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.