我一直收到错误的绑定变量错误。我已经尝试过调试它,但这仍然挥之不去,不太清楚为什么它在这里这么说。
我尝试做的事情就好像有人在1993年之前插入了enrols数据库那样他们就可以获得10%的折扣。此外,如果更新细节并在1993年开始之前注册,那么给他们10%的折扣。
errors:
6/31 PLS-00049: bad bind variable 'OLD.PAPER_COST'
6/50 PLS-00049: bad bind variable 'OLD.PAPER_COST'
14/31 PLS-00049: bad bind variable 'NEW.PAPER_COST'
14/50 PLS-00049: bad bind variable 'NEW.PAPER_COST'
不应该没关系,我没有在我的enrols关系中引用paper_cost,而是在我的论文关系中,因为我正在呼叫"更新论文"在paper_cost之前?
CREATE OR REPLACE TRIGGER discount_160
BEFORE INSERT OR UPDATE ON enrols
FOR EACH ROW
BEGIN
IF UPDATING THEN
IF (date_enrolled < TO_DATE('01-Jan-1993', 'dd-mon-yyyy')) THEN
IF (paper_code = 160) THEN
UPDATE papers
SET paper_cost = (:OLD.paper_cost - (:OLD.paper_cost * 0.1))
WHERE papers.paper_code = enrols.paper_code;
END IF;
END IF;
ELSE --inserting
IF (date_enrolled < TO_DATE('01-Jan-1993', 'dd-mon-yyyy')) THEN
IF (paper_code = 160) THEN
UPDATE papers
SET paper_cost = (:NEW.paper_cost - (:NEW.paper_cost * 0.1))
WHERE papers.paper_code = enrols.paper_code;
END IF;
END IF;
END IF;
END;
/
我的enrols关系:
CREATE TABLE enrols
(paper_code INT ,
student_id INT REFERENCES student(student_id),
date_enrolled DATE,
dept_id INT,
PRIMARY KEY(paper_code, student_id, dept_id),
FOREIGN KEY (paper_code, dept_id) REFERENCES papers(paper_code, dept_id));
INSERT INTO enrols VALUES
(160, 172384, TO_DATE('22-Mar-1994', 'dd-mon-yyyy'), 01);
INSERT INTO enrols VALUES
(444, 849294, TO_DATE('14-Jul-1992', 'dd-mon-yyyy'), 04);
INSERT INTO enrols VALUES
(160, 384583, TO_DATE('07-Aug-1995', 'dd-mon-yyyy'), 01);
INSERT INTO enrols VALUES
(160, 999999, TO_DATE('18-Aug-1991', 'dd-mon-yyyy'), 01);
我的论文关系:
CREATE TABLE papers
(paper_code INT,
EFTS INT NOT NULL,
dept_id INT REFERENCES departments(dept_id),
paper_cost INT,
PRIMARY KEY(paper_code, dept_id));
INSERT INTO papers VALUES
(160, 0.18, 01, 800);
任何帮助我指明正确方向的帮助都会很棒。
答案 0 :(得分:1)
触发器中有很多错误。
BEGIN
IF UPDATING THEN
(1) IF ([:new.|:old.]date_enrolled < TO_DATE('01-Jan-1993', 'dd-mon-yyyy')) THEN
(1) IF ([:new.|:old.]paper_code = 160) THEN
UPDATE papers
SET paper_cost = (:OLD.paper_cost - (:OLD.paper_cost * 0.1))
(2) WHERE papers.paper_code = <strike>enrols</strike>[:new].paper_code;
END IF;
END IF;
ELSE --inserting
(3) IF ([:new.]date_enrolled < TO_DATE('01-Jan-1993', 'dd-mon-yyyy')) THEN
(3) IF ([:new.]paper_code = 160) THEN
UPDATE papers
SET paper_cost = (:NEW.paper_cost - (:NEW.paper_cost * 0.1))
(2) WHERE papers.paper_code = <strike>enrols</strike>[:new].paper_code;
(1):触发器有两个可用的伪行:NEW和OLD。更新时,OLD行包含表中当前存在的数据。 NEW行包含更新完成后的行。所以你不能只召唤date_enrolled
。您的意思是:new.date_enrolled
还是:old.date_enrolled
? paper_code
在两个地方也是如此。
(2):您正在为表papers
发布Update语句,但您指的是enrols
。那个是从哪里来的?你还没有定义它。你和我知道你的意思是表enrols
,但编译器并不知道。此外,您不需要该表,您已经在该表的触发器中,并且您在其中一个伪行中拥有您需要的数据。我想你想要:NEW
中的那个,但这是你的决定。此外,由于paper_cost
似乎在两个表格中(不是最佳数据建模理念),您也应该更改:NEW.paper_cost
。
(3):在触发器的“插入”部分中,:OLD
伪行只有NULL,所以你想在这里使用:NEW
是非常安全的。
不是错误,只是一些技巧:声明一个名为oh,CutoffDate的本地日期变量来放置TO_DATE
调用的结果。然后只需引用该变量,而不是在两个地方调用该函数。此外,将值减少10%的更直接方法是SET paper_cost = :OLD.paper_cost * 0.9
。
另外,由于在插入和更新部分都执行相同的代码,为什么不将它们组合起来呢?
所以新的触发器看起来像这样:
CREATE OR REPLACE TRIGGER discount_160
BEFORE INSERT OR UPDATE ON enrols
FOR EACH ROW
DECLARE
CUTOFF DATE := TO_DATE( '01-Jan-1993', 'dd-mon-yyyy' );
BEGIN
IF :new.date_enrolled < CUTOFF AND
:new.paper_code = 160 THEN
:new.paper_cost := :old.paper_cost * 0.9;
UPDATE papers
SET paper_cost = :new.paper_cost
WHERE paper_code = :new.paper_code;
END IF;
END;
我还没有尝试过编译它,如果我在某个地方搞砸了或者你有疑问,请告诉我。
答案 1 :(得分:0)
您可以尝试在您的对帐单中将字段paper_cost
引用为papers.paper_cost
,而不是使用:NEW或:OLD