请帮助我代替触发器来计算和更新一些项目!

发布于 2024-10-21 00:39:32 字数 1219 浏览 1 评论 0原文

我必须创建一个触发器(而不是过程)来更新小计、运费、税费和总金额。基本上,所有这些属性都来自订单表,并且每个属性都涉及一些计算。小计 = Unit_Price * QTY 其中 Unit_Price 来自 Product 表,QTY 来自 Orderline 表。问题是当第一次创建订单表时,没有 exp_ship 和 exp_receive 日期,因此我必须更改订单表以添加这些新列。我不允许更改旧数据。因此,我创建了 Orders 表的副本用于记录,并一直在原始订单表上工作。现在,每次发出新订单时,我都必须编写一个触发器来计算小计、运费、税费和总计金额,并更新订单表中的这些字段。

我尝试了以下代码,但有很多错误。抱歉,我是第一次尝试这个。我还在学习过程中。我必须执行此操作的方法是创建一个视图并在该视图上使用“替代”触发器。即从视图中获取信息并更新订单表。

DROP VIEW ORDERS_V;

CREATE VIEW ORDERS_V AS

SELECT * FROM ORDERS;

CREATE OR REPLACE TRIGGER update_orders

INSTEAD OF INSERT ON ORDERS_V

FOR EACH ROW

DECLARE 

SHIPPING_COST NUMBER(6,3);

BEGIN

SELECT UNIT_PRICE INTO UNIT_PRICE FROM PRODUCT;

SELECT QTY INTO QTY FROM ORDERLINE;

SELECT SHIPPING_METHOD INTO SHIPPING_METHOD FROM ORDERS;

SELECT SUBTOTAL INTO SUBTOTAL FROM ORDERS;

UPDATE ORDERS 

    SET SUBTOTAL = UNIT_PRICE * QTY;

    IF SHIPPING_METHOD = 'GROUND' THEN

        shipping_cost := .05;

    ELSIF SHIPPING_METHOD = '1 DAY' THEN

        shipping_cost :=   .15;

    ELSIF SHIPPING_METHOD = '2 DAY' THEN

        shipping_cost :=   .10; 
    ELSE 

    shipping_cost := 0;        

    END IF;

UPDATE ORDERS

    SET shipping_charge = SUBTOTAL * shipping_cost;

END;

/

I have to create a trigger (not procedure) to update subtotal, shipping_charge, tax and total_amount. Basically, all these attributes come from orders table, and each of them involve some calculations. subtotal = Unit_Price * QTY where Unit_Price comes from Product table, and QTY comes from Orderline table. The problem is when the orders table was first created, there were no exp_ship and exp_receive dates so I had to alter the orders table to add these new columns. I am not allowed to change the old data. So, I created a copy of the Orders table for records, and have been working on the original orders table. Now, every time a new order is made, I have to write a trigger that would calculate the subtotal, shipping_charge, tax and total_amt, and update these fields in the orders table.

I tried the following code, but there are so many errors. I am sorry but I'm trying this for the first time. I am still in the learning process. The way I have to do it is by creating a view and using an Instead of trigger on the view. That is, get the information from the view and update the order table.

DROP VIEW ORDERS_V;

CREATE VIEW ORDERS_V AS

SELECT * FROM ORDERS;

CREATE OR REPLACE TRIGGER update_orders

INSTEAD OF INSERT ON ORDERS_V

FOR EACH ROW

DECLARE 

SHIPPING_COST NUMBER(6,3);

BEGIN

SELECT UNIT_PRICE INTO UNIT_PRICE FROM PRODUCT;

SELECT QTY INTO QTY FROM ORDERLINE;

SELECT SHIPPING_METHOD INTO SHIPPING_METHOD FROM ORDERS;

SELECT SUBTOTAL INTO SUBTOTAL FROM ORDERS;

UPDATE ORDERS 

    SET SUBTOTAL = UNIT_PRICE * QTY;

    IF SHIPPING_METHOD = 'GROUND' THEN

        shipping_cost := .05;

    ELSIF SHIPPING_METHOD = '1 DAY' THEN

        shipping_cost :=   .15;

    ELSIF SHIPPING_METHOD = '2 DAY' THEN

        shipping_cost :=   .10; 
    ELSE 

    shipping_cost := 0;        

    END IF;

UPDATE ORDERS

    SET shipping_charge = SUBTOTAL * shipping_cost;

END;

/

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

黯淡〆 2024-10-28 00:39:32

目前您的触发器正在处理整个表。这显然不是你想要的。因此,您需要向这些语句添加 WHERE 子句,以便将活动限制在所需的行。在触发器中,我们使用 :NEW. 表示法来获取触发表中列的值。像这样的事情:

    SELECT UNIT_PRICE INTO :new.UNIT_PRICE FROM PRODUCT
    where product_id = :new.product_id;

    SELECT QTY INTO :new.QTY FROM ORDERLINE
    where order_id = :new.order_id;

另一个语法更正:我们可以在更新中包含多个列。这比发布多个声明要好。

UPDATE ORDERS 
SET :new.SUBTOTAL = ( :new.UNIT_PRICE * :new.QTY )
    , :new.shipping_charge = ( :new.SUBTOTAL * shipping_cost ) -- ??? see below
where order_id = :new.order_id
;

我确实打算重写你的整个触发器。然而你的逻辑仍然令人困惑(你会记得我建议你在我的回答中澄清一些事情 你之前的问题)。您需要理清的事情:

  1. 您的触发器在 INSTEAD OF INSERT 上触发,但您的代码更新了基础表中的现有记录。嗯?

  2. 您正在从订单行中进行选择。预期的数据模型将是具有一个或多个行的订单。如果是这样,您的代码应该处理 ORDERLINE (我猜是 PRODUCT)的多行。

  3. 您从基础表中选择了 SUBTOTAL,尽管随后您似乎覆盖了该值。然后,您在计算中使用 SUBTOTAL:您认为您正在使用 SUBTOTAL 的哪个值?

At the moment your trigger is working with whole tables. This is obviously not what you want. So you need to add WHERE clauses to those statements, in order to restrict the activity to the required rows. In triggers we use the :NEW. notation to get the values of columns in the triggering table. Something like this:

    SELECT UNIT_PRICE INTO :new.UNIT_PRICE FROM PRODUCT
    where product_id = :new.product_id;

    SELECT QTY INTO :new.QTY FROM ORDERLINE
    where order_id = :new.order_id;

Another syntax correction: we can include several columns in an UPDATE. This is better than issuing multiple statements.

UPDATE ORDERS 
SET :new.SUBTOTAL = ( :new.UNIT_PRICE * :new.QTY )
    , :new.shipping_charge = ( :new.SUBTOTAL * shipping_cost ) -- ??? see below
where order_id = :new.order_id
;

I did intend to re-write your whole trigger. However your logic remains confusing (you will recall I suggested you clarify things in my answer to your previous question). Things you need to straighten out:

  1. Your trigger fires on INSTEAD OF INSERT but your code UPDATES existing records in the underlying table. Huh?

  2. You are selecting from ORDERLINE. The expected data model would be an ORDER to have one or more LINES. If this is so, your code ought to handle multiple rows for ORDERLINE (and I guess PRODUCT).

  3. You select SUBTOTAL from the underlying table although subsequently you appear to overwrite the value. Then you use SUBTOTAL in a calculation: which value of SUBTOTAL do you think you're using?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文