我的 SQL 代码的正确原型是什么?
What is the right prototype for my SQL code?
我是新手 SQL,我正在尝试使用 SQLcl:
对这两个 table 应用三角函数
prodc
( PRODC_NAME, 折扣字符 (1) 默认值 'N',
PK 主键 (PRODC_NAME));
peopleOrder
( ORDERID, PRODC_NAME,
PRIMARY KEY (ORDERID, PRODC_NAME),
FOREIGN KEY (PRODC_NAME) REFERENCES PRODC (PRODC_NAME));
我希望我的触发器执行以下操作:
当我将行更新或插入到 peopleOrder
时,触发器应检查行的 product_name
是否在位于 [=17= 的折扣列中具有值 'N' ] table;如果它没有 'N' 值,它应该显示一条错误消息。
我尝试了很多方法和下面的触发器,但是当我插入行时,触发器似乎不起作用并且对行没有影响:
CREATE OR REPLACE TRIGGER constraint_1
After UPDATE OR INSERT on peopleOrder
for each row
begin
if not (:new.prodc_name in
(select prodc_name from prodc where discounted = 'N' )) then
RAISE_ERROR(-30001, 'No product can be ordered
!');
END IF;
INSERT INTO peopleOrder VALUES (:new.ORDERID, :new.PRODC_NAME);
END;
/
我的插入命令是:
INSERT INTO peopleOder (ORDERID, PRODC_NAME)
VALUES (251, 'Puton');
和 'Puton' 在 prodc table.
的折扣列中具有值 'N'
您首先需要了解触发器是什么。它是 作为 导致其触发的语句的一部分运行的一段代码。因此,您 不能 引用 table 导致它触发。通常这是完全没有必要的。每个行触发器都可以访问 2 行:现有数据(旧)和结果数据(新)的副本。更新已填充并且 Insert/Delete 仅 new/old 适用于操作。 before 语句触发器可以修改新数据,after 触发器不能。这些行允许您在没有 DML 或 select 的情况下处理 table 中的列。 (但是你不能 'scan' table)。在任何级别,触发器都可能引发异常,从而停止整个过程和调用语句。如果未引发异常,则处理调用收益。有关更完整的描述,请参阅 PL/SQL Language Reference 或您使用的 Oracle 版本 运行。
在这种情况下,您的触发器分解为一个 if
声明。
-- Revised. Orig missed that flag comming from different table.
create or replace trigger constraint_1
before update or insert on peopleOrder
for each row
declare
dis_num integer;
begin
select count(*)
into dis_num
from product
where discounted != 'N'
and product_name = :new.product_name
and rownum < 2;
if dis_num != 0 then
raise_application_error(-20001, 'No discounted product can be ordered!');
end if;
end constraint_1;
-- Orig ==============================================
CREATE OR REPLACE TRIGGER constraint_1
before UPDATE OR INSERT on peopleOrder
for each row
begin
if :new.discounted = 'N' then
RAISE_APPLICATION_ERROR(-20001, 'No discounted product can be ordered')
end if;
END;
/
我是新手 SQL,我正在尝试使用 SQLcl:
对这两个 table 应用三角函数prodc
( PRODC_NAME, 折扣字符 (1) 默认值 'N', PK 主键 (PRODC_NAME));
peopleOrder
( ORDERID, PRODC_NAME,
PRIMARY KEY (ORDERID, PRODC_NAME),
FOREIGN KEY (PRODC_NAME) REFERENCES PRODC (PRODC_NAME));
我希望我的触发器执行以下操作:
当我将行更新或插入到 peopleOrder
时,触发器应检查行的 product_name
是否在位于 [=17= 的折扣列中具有值 'N' ] table;如果它没有 'N' 值,它应该显示一条错误消息。
我尝试了很多方法和下面的触发器,但是当我插入行时,触发器似乎不起作用并且对行没有影响:
CREATE OR REPLACE TRIGGER constraint_1
After UPDATE OR INSERT on peopleOrder
for each row
begin
if not (:new.prodc_name in
(select prodc_name from prodc where discounted = 'N' )) then
RAISE_ERROR(-30001, 'No product can be ordered
!');
END IF;
INSERT INTO peopleOrder VALUES (:new.ORDERID, :new.PRODC_NAME);
END;
/
我的插入命令是:
INSERT INTO peopleOder (ORDERID, PRODC_NAME)
VALUES (251, 'Puton');
和 'Puton' 在 prodc table.
的折扣列中具有值 'N'您首先需要了解触发器是什么。它是 作为 导致其触发的语句的一部分运行的一段代码。因此,您 不能 引用 table 导致它触发。通常这是完全没有必要的。每个行触发器都可以访问 2 行:现有数据(旧)和结果数据(新)的副本。更新已填充并且 Insert/Delete 仅 new/old 适用于操作。 before 语句触发器可以修改新数据,after 触发器不能。这些行允许您在没有 DML 或 select 的情况下处理 table 中的列。 (但是你不能 'scan' table)。在任何级别,触发器都可能引发异常,从而停止整个过程和调用语句。如果未引发异常,则处理调用收益。有关更完整的描述,请参阅 PL/SQL Language Reference 或您使用的 Oracle 版本 运行。 在这种情况下,您的触发器分解为一个 if 声明。
-- Revised. Orig missed that flag comming from different table.
create or replace trigger constraint_1
before update or insert on peopleOrder
for each row
declare
dis_num integer;
begin
select count(*)
into dis_num
from product
where discounted != 'N'
and product_name = :new.product_name
and rownum < 2;
if dis_num != 0 then
raise_application_error(-20001, 'No discounted product can be ordered!');
end if;
end constraint_1;
-- Orig ==============================================
CREATE OR REPLACE TRIGGER constraint_1
before UPDATE OR INSERT on peopleOrder
for each row
begin
if :new.discounted = 'N' then
RAISE_APPLICATION_ERROR(-20001, 'No discounted product can be ordered')
end if;
END;
/