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

时间:2019-06-01 08:34:32

标签: regex oracle plsql database-trigger

我正在使用触发器,该触发器使用函数为名为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:在“dominioMolteplicità”行3中
  ORA-04088:执行“dominioMolteplicità”触发器时发生错误

(请注意,如果我禁用触发器,则insert语句可以正常工作。触发器存在一些问题,但我找不到错误。)

2 个答案:

答案 0 :(得分:2)

它与触发器无关。

如果提供的字符串(在这种情况下为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 :(得分:1)

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

我想regexp_like( lower(mol), '\*..\*')没问题,在这种情况下,molteplicità的值'*=-*''*34*'会起作用。

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

演示:

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'而言)。