将值插入表中时,插入触发器(2行)之前的超级简单操作不起作用

时间:2019-06-01 18:16:49

标签: sql oracle

我正在构建一个触发器,如果​​字符串的长度不为16,则会引发应用程序错误。

CREATE OR REPLACE TRIGGER lunghezza_CF
before INSERT OR UPDATE ON Persona
FOR each ROW
BEGIN
    IF LENGTH(:NEW.CF) <> 16 THEN
        RAISE_APPLICATION_ERROR(-20002, 'CF length must be 16');
    END IF;
END;

Persona的组成如下:

CF char(16) primary key
...

如果我写以下语句

insert into Persona(CF) values('ABC12')

由于什么原因将“ ABC12”插入表中?出于某种原因,我的触发器无法正常工作,但似乎还可以...

(请注意,LENGTH(string)是Oracle的“内置”函数)

1 个答案:

答案 0 :(得分:4)

问题是您正在使用char数据类型,该数据类型空白填充到所定义的长度,因此始终与定义的长度一样长。您可以使用trim()删除空格。

CREATE OR REPLACE TRIGGER lunghezza_CF
before INSERT OR UPDATE ON Persona
FOR each ROW
BEGIN
    IF LENGTH(TRIM(:NEW.CF)) <> 16 THEN
        RAISE_APPLICATION_ERROR(-20002, 'CF length must be 16');
    END IF;
END;

db<>fiddle

但是,除了触发器之外,您还可以为此简单地使用检查约束。

ALTER TABLE persona
            ADD CHECK (length(trim(cf)) = 16);

db<>fiddle

请注意,trim()会删除尾随和前导的空格。如果要计算前导空格,则可以改用rtrim(),它会删除尾随空格。