【问题标题】:update query adding old data too even after changing id即使在更改 id 后也更新查询添加旧数据
【发布时间】:2019-02-08 05:04:16
【问题描述】:

创建一个接受 2 个参数的过程,分别代表 inv_id 和价格上涨百分比。伪函数应该首先用新价格更新数据库,然后返回新价格和手头数量。 创建第二个名为 L4Q3 的过程,它接受 inv_id 和价格上涨百分比。该程序将使用旧程序显示库存的新值(提示:值 = 价格 X 现有数量)

CREATE OR REPLACE PROCEDURE ex3 (p_inv_id IN NUMBER, p_change IN NUMBER, 
p_new_price OUT NUMBER, p_qoh OUT NUMBER)
AS
v_new_price NUMBER(6,2);
v_qoh NUMBER(6,2);
BEGIN
UPDATE inventory 
SET inv_price = (SELECT inv_price + (inv_price*(p_change/100))
FROM inventory
WHERE inv_id = p_inv_id);
COMMIT;
SELECT inv_price, inv_qoh
INTO p_new_price, p_qoh
FROM inventory
WHERE inv_id = p_inv_id;
COMMIT;
v_qoh := p_qoh;
v_new_price := p_new_price;
DBMS_OUTPUT.PUT_LINE('hello'||v_new_price);
END;
/ 


CREATE OR REPLACE PROCEDURE use_ex3 ( p_inv_id NUMBER, p_change NUMBER)
AS
v_new_price NUMBER(6,2);
v_qoh NUMBER(6,2);
v_value NUMBER(10,2);
BEGIN
ex3(p_inv_id, p_change, v_new_price, v_qoh);
v_value := v_new_price*v_qoh;
DBMS_OUTPUT.PUT_LINE('value is:'||v_value);
END; 
/

【问题讨论】:

    标签: oracle stored-procedures plsql


    【解决方案1】:

    考虑转换您的程序,如下所示:

    SQL> set serveroutput on;
    SQL> CREATE OR REPLACE PROCEDURE ex3(p_inv_id    IN  inventory.inv_id%type,
                                         p_change    IN  NUMBER,
                                         p_new_price OUT inventory.inv_price%type,
                                         p_qoh       OUT inventory.inv_qoh%type) AS
    BEGIN
      UPDATE inventory
         SET inv_price = inv_price * ( 1 + (p_change / 100) )
       WHERE inv_id = p_inv_id
       RETURNING inv_price, inv_qoh 
            INTO p_new_price, p_qoh;
    
      DBMS_OUTPUT.PUT_LINE('hello '|| p_new_price);
    END;
    /
    SQL> CREATE OR REPLACE PROCEDURE use_ex3(p_inv_id inventory.inv_id%type, p_change NUMBER) AS
            v_new_price inventory.inv_price%type;
            v_qoh       inventory.inv_qoh%type;
            v_value     NUMBER(10, 2);
    BEGIN
       ex3(p_inv_id, p_change, v_new_price, v_qoh);
       v_value := v_new_price * v_qoh;
       DBMS_OUTPUT.PUT_LINE('value is: '|| v_value);
    END;
    

    核心问题是

    UPDATE 语句中缺少过滤器 WHERE inv_id = p_inv_id。 即不限于只有一个inv_id

    此外,考虑以下事项将使您的代码更好:

    • 不需要SET 子句的子查询,只需要一个赋值为inv_price = inv_price * ( 1 + (p_change / 100) )
    • 最好将列的变量类型定义为 inventory.<column_name>%type
    • 不需要额外的局部变量,例如v_new_priceout p_new_price 等过程的参数可以用作 分配目标
    • 不需要UPDATE之后的SELECT语句,使用RETURNING INTO就足够了
    • 别忘了使用set serveroutput on打印结果

    • 我认为在单个程序中排除commit是一个好习惯 单位为数据一致性提供事务完整性 获得 DML 的表。最好在调用者中只保留一个commit 应用在所有语句和程序单元的末尾。

    【讨论】:

    • 错误答案,第二个程序应该被称为L4Q3。开个玩笑,很好,详细的答案;-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-26
    • 2019-06-16
    • 2021-07-26
    • 1970-01-01
    • 1970-01-01
    • 2017-09-24
    • 1970-01-01
    相关资源
    最近更新 更多