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位:

  1. 删除最后一位数字
  2. 前面加了978
  3. 添加校验位,由公式

    计算

    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