【问题标题】:Ora 06512/04088 triggers errors when INSERT INTO statementora 06512/04088 INSERT INTO 语句时触发错误
【发布时间】:2019-10-17 16:41:14
【问题描述】:

我正在为一个触发器工作,该触发器使用函数在名为 Partecipa 的表中为列 Molteplicità 提供“域”。

我创建的触发器如下:

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à”期间出错

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

【问题讨论】:

  • 看起来您的问题是为什么 '*..*' 与您的正则表达式 ' [*]\..[*] ' 不匹配。是空间。
  • 有些鬼鬼祟祟。 *..* 应该被正则表达式接受,正如link 所说

标签: regex oracle plsql database-trigger


【解决方案1】:

与触发器无关。

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

【讨论】:

    【解决方案2】:

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

    我想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
    

    附:请注意,anticipated_pattern 也会失败(对于上述示例中的 mol = 'B')。

    【讨论】:

      猜你喜欢
      • 2015-08-06
      • 2013-11-29
      • 2022-01-20
      • 1970-01-01
      • 1970-01-01
      • 2023-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多