Oracle SQL: PLS-00049 从序列中选择 NEXTVAL 时绑定变量错误
Oracle SQL: PLS-00049 Bad Bind variable when selecting NEXTVAL from a sequence
所以,我正在尝试使用 JDBC 访问我的 Oracle 数据库,我发现,对于 JDBC 到 return 中的函数正确的结果,我需要为我的 table 制作一个迭代器。因此,在四处搜索并弄清楚这意味着什么之后,我想出了以下代码片段来完成它:
--create a sequence for use in the trigger
CREATE SEQUENCE accounts_seq;
--make the trigger on insert or update
CREATE OR REPLACE TRIGGER account_pk_trig
BEFORE INSERT OR UPDATE ON accounts
FOR EACH ROW
BEGIN
IF inserting THEN
SELECT : accounts_seq.NEXTVAL INTO : NEW.accountnumber FROM dual;
ELSE IF updating THEN
SELECT : OLD.accountnumber INTO : NEW.accountnumber FROM dual;
END IF;
END IF;
END;
/
并且,不仅 Oracle SQL 开发人员将可怕的厄运红色下划线放在分号后的 space 中,而且还在正斜杠上结束代码块。就我所见,这对于我所见过的 Oracle SQL 触发器定义示例来说似乎是正确的......我不确定这是否是由于 Oracle SQL 开发人员没有将 NEXTVAL 识别为关键字...因为它没有像其他关键字那样突出显示。
经过一番折腾,我发现 "ELSE IF" 打开了一个我没有关闭的新 IF 语句。但是,仍然出现 Bad Bind 变量错误。
对于那些想要确保 "accountnumber" 字段存在于 table "accounts" 中的人,这是我对 "accounts" [=34] 的定义=].
CREATE TABLE accounts (
accountnumber NUMBER NOT NULL,
routingnumber NUMBER NOT NULL,
acctype VARCHAR2(20),
balance NUMBER (*,2),
ownerid NUMBER,
CONSTRAINT accountnumber_pk PRIMARY KEY (accountnumber)
);
您的 PL/SQL 代码中有两个主要错误:
首先select :
是错误的。你不能像那样扔一个冒号。 NEW
和 OLD
记录 do 需要一个冒号,但是 没有 一个 space。 :new
,不是 : new
。
要将查询结果存储在您需要的变量中:
select accounts_seq.NEXTVAL
INTO :NEW.accountnumber
FROM dual;
但是你不需要 SELECT
,你可以使用简单的 variable assignment:
:NEW.accountnumber := accounts_seq.NEXTVAL;
虽然你只有一个 IF
,但你也有两个 END IF
而as documented in the manual需要是ELSIF
,而不是ELSE IF
将所有这些放在一起,您的触发器应该是:
CREATE OR REPLACE TRIGGER account_pk_trig
BEFORE INSERT OR UPDATE ON accounts
FOR EACH ROW
BEGIN
IF inserting THEN
:NEW.accountnumber := accounts_seq.NEXTVAL;
ELSIF updating THEN
:NEW.accountnumber := :OLD.accountnumber;
END IF;
END;
/
由于触发器被声明为BEFORE INSERT OR UPDATE
,所以ELSIF
实际上是没有用的,因为它只能是insert
或updating
。所以你可以简单地写 ELSE
而不是 ELSIF updating THEN
所以,我正在尝试使用 JDBC 访问我的 Oracle 数据库,我发现,对于 JDBC 到 return 中的函数正确的结果,我需要为我的 table 制作一个迭代器。因此,在四处搜索并弄清楚这意味着什么之后,我想出了以下代码片段来完成它:
--create a sequence for use in the trigger
CREATE SEQUENCE accounts_seq;
--make the trigger on insert or update
CREATE OR REPLACE TRIGGER account_pk_trig
BEFORE INSERT OR UPDATE ON accounts
FOR EACH ROW
BEGIN
IF inserting THEN
SELECT : accounts_seq.NEXTVAL INTO : NEW.accountnumber FROM dual;
ELSE IF updating THEN
SELECT : OLD.accountnumber INTO : NEW.accountnumber FROM dual;
END IF;
END IF;
END;
/
并且,不仅 Oracle SQL 开发人员将可怕的厄运红色下划线放在分号后的 space 中,而且还在正斜杠上结束代码块。就我所见,这对于我所见过的 Oracle SQL 触发器定义示例来说似乎是正确的......我不确定这是否是由于 Oracle SQL 开发人员没有将 NEXTVAL 识别为关键字...因为它没有像其他关键字那样突出显示。
经过一番折腾,我发现 "ELSE IF" 打开了一个我没有关闭的新 IF 语句。但是,仍然出现 Bad Bind 变量错误。
对于那些想要确保 "accountnumber" 字段存在于 table "accounts" 中的人,这是我对 "accounts" [=34] 的定义=].
CREATE TABLE accounts (
accountnumber NUMBER NOT NULL,
routingnumber NUMBER NOT NULL,
acctype VARCHAR2(20),
balance NUMBER (*,2),
ownerid NUMBER,
CONSTRAINT accountnumber_pk PRIMARY KEY (accountnumber)
);
您的 PL/SQL 代码中有两个主要错误:
首先select :
是错误的。你不能像那样扔一个冒号。 NEW
和 OLD
记录 do 需要一个冒号,但是 没有 一个 space。 :new
,不是 : new
。
要将查询结果存储在您需要的变量中:
select accounts_seq.NEXTVAL
INTO :NEW.accountnumber
FROM dual;
但是你不需要 SELECT
,你可以使用简单的 variable assignment:
:NEW.accountnumber := accounts_seq.NEXTVAL;
虽然你只有一个 IF
END IF
而as documented in the manual需要是ELSIF
,而不是ELSE IF
将所有这些放在一起,您的触发器应该是:
CREATE OR REPLACE TRIGGER account_pk_trig
BEFORE INSERT OR UPDATE ON accounts
FOR EACH ROW
BEGIN
IF inserting THEN
:NEW.accountnumber := accounts_seq.NEXTVAL;
ELSIF updating THEN
:NEW.accountnumber := :OLD.accountnumber;
END IF;
END;
/
由于触发器被声明为BEFORE INSERT OR UPDATE
,所以ELSIF
实际上是没有用的,因为它只能是insert
或updating
。所以你可以简单地写 ELSE
ELSIF updating THEN