обновить запрос, добавив старые данные, даже после изменения идентификатора - PullRequest
0 голосов
/ 07 февраля 2019

Создайте процедуру, которая принимает 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; 
/

1 Ответ

0 голосов
/ 07 февраля 2019

Рассмотрите возможность преобразования ваших процедур, как показано ниже:

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 внутри приложения вызывающей стороны.

...