创建一个过程,该过程接受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;
/
答案 0 :(得分: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;
核心问题是
在WHERE inv_id = p_inv_id
语句中缺少过滤器UPDATE
。
即不只限于一个inv_id
此外考虑以下事项将使您的代码更好:
SET
子句的子查询,只需分配一个inv_price = inv_price * ( 1 + (p_change / 100) )
inventory.<column_name>%type
v_new_price
,out
诸如p_new_price
之类的过程的参数可以用作
分配目标SELECT
之后的UPDATE
语句,使用RETURNING
INTO
就足够了不要忘记使用set serveroutput on
打印出结果
我认为在单个程序中排除commit
是一个好习惯
提供交易完整性以确保数据一致性的单元
DML的表格。建议在呼叫者内只保留一个commit
所有语句和程序单元末尾的应用程序。