PL/SQL: 更改插入数据时触发错误
PL/SQL: trigger error on altering insert data
我正在尝试为 table 本书编写触发器。为此table,
create table books (
isbn VARCHAR(13) CHECK (LENGTH (isbn) = 10 or LENGTH (isbn) = 13),
...
PRIMARY KEY (isbn)
);
我想写一个触发器,当插入长度为10的isbn时,按照以下规则将格式改为13位:
- 删除最后一位数字
- 前面加了978
添加校验位,由公式
计算
CHECK_BIT = (10 - (x1 + 3*x2 + x3 + 3*x4 + ... + x11 + 3*x12) mod 10) mod 10
代码:
create or replace trigger isbnFormatChange
before insert on books
for each row
begin
if (length (:new.isbn) = 10) then
:new.isbn := substr (:new.isbn, 1, 9);
:new.isbn := concat (978, :new.isbn);
:new.isbn := concat (:new.isbn, mod ((10 - mod ((to_number (substr (:new.isbn, 1, 1)) + 3 * to_number (substr (:new.isbn, 2, 1)) + to_number (substr (:new.isbn, 3, 1)) + 3 * to_number (substr (:new.isbn, 4, 1)) + to_number (substr (:new.isbn, 5, 1)) + 3 * to_number (substr (:new.isbn, 6, 1)) + to_number (substr (:new.isbn, 7, 1)) + 3 * to_number (substr (:new.isbn, 8, 1)) + to_number (substr (:new.isbn, 9, 1)) + 3 * to_number (substr (:new.isbn, 10, 1)) + to_number (substr (:new.isbn, 11, 1)) + 3 * to_number (substr (:new.isbn, 12, 1))), 10)), 10));
end if;
end;
但它给出了以下错误:
Error(5,5): PL/SQL: Statement ignored
Error(5,63): PLS-00330: invalid use of type name or subtype name
我想我做错了第 3 步(公式部分)
函数convert
用于不同字符类型之间的相互转换。要将字符串转换为数字,请使用函数 to_number
。所以你只需要在你的代码中将所有 convert (int, ...)
替换为 to_number()
函数:
create or replace trigger isbnFormatChange
before insert on books
for each row
begin
if (length (:new.isbn) = 10) then
:new.isbn := substr (:new.isbn, 1, 9);
:new.isbn := concat (978, :new.isbn);
:new.isbn := concat (:new.isbn, mod ((10 - mod ((to_number(substr (:new.isbn, 1, 1)) + 3 * to_number(substr (:new.isbn, 2, 1)) + to_number(substr (:new.isbn, 3, 1)) + 3 * to_number(substr (:new.isbn, 4, 1)) + to_number( substr (:new.isbn, 5, 1)) + 3 * to_number( substr (:new.isbn, 6, 1)) + to_number(substr (:new.isbn, 7, 1)) + 3 * to_number( substr (:new.isbn, 8, 1)) + to_number( substr (:new.isbn, 9, 1)) + 3 * to_number( substr (:new.isbn, 10, 1)) + to_number(substr (:new.isbn, 11, 1)) + 3 * to_number( substr (:new.isbn, 12, 1))), 10)), 10));
end if;
end;
/
convert
文档中的函数:http://docs.oracle.com/cd/B28359_01/server.111/b28286/functions027.htm#SQLRF00620
to_number
文档中的函数:http://docs.oracle.com/cd/E11882_01/server.112/e41084/functions211.htm#SQLRF06140
我正在尝试为 table 本书编写触发器。为此table,
create table books (
isbn VARCHAR(13) CHECK (LENGTH (isbn) = 10 or LENGTH (isbn) = 13),
...
PRIMARY KEY (isbn)
);
我想写一个触发器,当插入长度为10的isbn时,按照以下规则将格式改为13位:
- 删除最后一位数字
- 前面加了978
添加校验位,由公式
计算CHECK_BIT = (10 - (x1 + 3*x2 + x3 + 3*x4 + ... + x11 + 3*x12) mod 10) mod 10
代码:
create or replace trigger isbnFormatChange
before insert on books
for each row
begin
if (length (:new.isbn) = 10) then
:new.isbn := substr (:new.isbn, 1, 9);
:new.isbn := concat (978, :new.isbn);
:new.isbn := concat (:new.isbn, mod ((10 - mod ((to_number (substr (:new.isbn, 1, 1)) + 3 * to_number (substr (:new.isbn, 2, 1)) + to_number (substr (:new.isbn, 3, 1)) + 3 * to_number (substr (:new.isbn, 4, 1)) + to_number (substr (:new.isbn, 5, 1)) + 3 * to_number (substr (:new.isbn, 6, 1)) + to_number (substr (:new.isbn, 7, 1)) + 3 * to_number (substr (:new.isbn, 8, 1)) + to_number (substr (:new.isbn, 9, 1)) + 3 * to_number (substr (:new.isbn, 10, 1)) + to_number (substr (:new.isbn, 11, 1)) + 3 * to_number (substr (:new.isbn, 12, 1))), 10)), 10));
end if;
end;
但它给出了以下错误:
Error(5,5): PL/SQL: Statement ignored
Error(5,63): PLS-00330: invalid use of type name or subtype name
我想我做错了第 3 步(公式部分)
函数convert
用于不同字符类型之间的相互转换。要将字符串转换为数字,请使用函数 to_number
。所以你只需要在你的代码中将所有 convert (int, ...)
替换为 to_number()
函数:
create or replace trigger isbnFormatChange
before insert on books
for each row
begin
if (length (:new.isbn) = 10) then
:new.isbn := substr (:new.isbn, 1, 9);
:new.isbn := concat (978, :new.isbn);
:new.isbn := concat (:new.isbn, mod ((10 - mod ((to_number(substr (:new.isbn, 1, 1)) + 3 * to_number(substr (:new.isbn, 2, 1)) + to_number(substr (:new.isbn, 3, 1)) + 3 * to_number(substr (:new.isbn, 4, 1)) + to_number( substr (:new.isbn, 5, 1)) + 3 * to_number( substr (:new.isbn, 6, 1)) + to_number(substr (:new.isbn, 7, 1)) + 3 * to_number( substr (:new.isbn, 8, 1)) + to_number( substr (:new.isbn, 9, 1)) + 3 * to_number( substr (:new.isbn, 10, 1)) + to_number(substr (:new.isbn, 11, 1)) + 3 * to_number( substr (:new.isbn, 12, 1))), 10)), 10));
end if;
end;
/
convert
文档中的函数:http://docs.oracle.com/cd/B28359_01/server.111/b28286/functions027.htm#SQLRF00620
to_number
文档中的函数:http://docs.oracle.com/cd/E11882_01/server.112/e41084/functions211.htm#SQLRF06140