所以,我正在尝试使用JDBC访问我的Oracle数据库,我发现,为了使JDBC中的函数正确返回结果,我需要为我的表创建一个迭代器。因此,在搜索并弄清楚这意味着什么后,我想出了以下代码片段来完成这项工作:
--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 Developer在分号结束之后在空间中放置了可怕的红色下划线,而且还使用正斜杠来结束代码块。据我所知,这看起来对于我见过的触发器定义的Oracle SQL示例是正确的......我不确定这是否是由于Oracle SQL Developer没有将NEXTVAL识别为关键字...因为它没有像其他人一样突出显示。
经过一番摆弄后,我意识到“ELSE IF”开启了一个我没有关闭的新IF声明。但是,仍然会出现Bad Bind变量错误。
对于那些想要确保“帐户”表中存在“accountnumber”字段的人,这是我对“帐户”表的定义。
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)
);
答案 0 :(得分:1)
PL / SQL代码中有两个主要错误:
首先select :
是错误的。你不能像这样扔一个冒号。 NEW
和OLD
记录执行需要冒号,但没有空格。 :new
,而非: new
。
将查询结果存储在您需要的变量中:
select accounts_seq.NEXTVAL
INTO :NEW.accountnumber
FROM dual;
但是你不需要SELECT
,你可以使用一个简单的variable assignment:
:NEW.accountnumber := accounts_seq.NEXTVAL;
虽然您只有一个END IF
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
。因此,您只需编写ELSIF updating THEN
ELSE