2015-12-01 2 views
0

Вопрос: Обработать транзакции и определить влияние на инвентарь. Отображать информацию, которая дает исходный инвентарь и инвентарь после продажи, возврата и покупки, с использованием курсоров.PL/SQL Курсор с использованием таблиц инвентаризации и транзакций

Мои две таблицы:

Таблица один Itemid, ItemName и Quanity.

ITEM ITEMNAME      QUANITY 
---- ------------------------- ---------- 
1111 Computer       50 
2222 TV        10 
3333 Camera       35 
4444 Phone        40 

И

Таблица два является ItemId, ITEMNAME, код (ы = продажа, г = возврат, р = покупки), и itemsmoved (со ссылкой на code..example 1111 продано 2)

ITEM ITEMNAME     C ITEMSMOVED 
---- ------------------------- - ---------- 
1111 Computer     S   2 
2222 TV      S   5 
3333 Camera     S   15 
4444 Phone      S   7 
1111 Computer     P   10 
2222 TV      R   2 
3333 Camera     P   20 
4444 Phone      R   3 

Я также создал таблицу для вставки в:

SQL> create table updatedinv 
    2 (itemid varchar2(4), 
    3 itemname varchar2(15), 
    4 orginv number(4), 
    5 updatedinv number(4)); 

Мой PL/SQL-код:

SET SERVEROUTPUT ON 
DECLARE 
    v_idno  inventory.itemid%TYPE; 
    v_name  inventory.itemname%TYPE; 
    v_quantity inventory.quanity%TYPE; 
    v_tidno  transaction.itemid%TYPE; 
    v_code  transaction.code%TYPE; 
    v_move  transaction.itemsmoved%TYPE; 
    v_updated updatedinv.updatedinv%TYPE; 
    CURSOR inventory_cursor IS 
    SELECT itemid, itemname, quanity FROM inventory 
    ORDER BY itemid; 
    CURSOR transaction_cursor IS 
    SELECT itemid, code, itemsmoved FROM transaction 
    WHERE v_idno = itemid 
    ORDER BY itemid; 
    BEGIN 
    OPEN inventory_cursor; 
    LOOP 
     FETCH inventory_cursor INTO v_idno, v_name, v_quantity; 
     EXIT WHEN inventory_cursor%NOTFOUND; 
     IF transaction_cursor%ISOPEN THEN 
     CLOSE transaction_cursor; 
     END IF; 
     OPEN transaction_cursor; 
     v_updated := 0; 
     LOOP 
     FETCH transaction_cursor INTO v_tidno, v_code, v_move; 
     EXIT WHEN transaction_cursor%NOTFOUND; 
     IF v_code = 'S' THEN 
     v_updated := v_quantity - v_move; 
     END IF; 
     IF v_code = 'R' THEN 
     v_updated := v_quantity + v_move; 
     END IF; 
     IF v_code = 'P' THEN 
     v_updated := v_quantity + v_move; 
     END IF; 
       END LOOP; 
     INSERT into updatedinv 
      VALUES(v_idno, v_name, v_quantity, v_updated); 
     CLOSE transaction_cursor; 
    END LOOP; 
    CLOSE inventory_cursor; 
END; 
/
SET SERVEROUTPUT OFF 

Он вычисляет код P и R, но не S, продажи не получают minused до покупки или возврата:

SQL> @ loop1 

PL/SQL procedure successfully completed. 

SQL> select * 
    2 from updatedinv; 

ITEM ITEMNAME   ORGINV UPDATEDINV 
---- --------------- ---------- ---------- 
1111 Computer    50   60 
2222 TV      10   12 
3333 Camera     35   55 
4444 Phone     40   43 

Результаты должны выглядеть следующим образом:

SQL> select * 
    2 from updatedinv; 

ITEM ITEMNAME   ORGINV UPDATEDINV 
---- --------------- ---------- ---------- 
1111 Computer    50   58 
2222 TV      10   7 
3333 Camera     35   40 
4444 Phone     40   36 
+0

Пожалуйста, покажите некоторые данные результата из ваших данных образца, недостаточно ясно, что вы пытаетесь выполнить здесь. –

+0

Я пытаюсь взять таблицу два, чтобы обновить таблицу с курсорами –

+0

@JorgeCampos i обновлен с кодом –

ответ

0

Привет Если я правильно понимаю вас вопрос правильно вопрос с вашим кодом в этой строке

v_updated := v_quantity - v_move; 

Каждый раз, когда вы идете через петлю вы добавляете/вычесть из v_quantity (что никогда не меняется), так что будет эффективно только процесс последней транзакции.

См. Измененный цикл ниже, установив v_updated равным v_quantity перед циклом, а затем используя только v_updated для ваших вычислений во время цикла, вы должны получить точные результаты.

OPEN inventory_cursor; 
LOOP 
    FETCH inventory_cursor INTO v_idno, v_name, v_quantity; 
    EXIT WHEN inventory_cursor%NOTFOUND; 
    IF transaction_cursor%ISOPEN THEN 
    CLOSE transaction_cursor; 
    END IF; 
    v_updated := v_quantity; -- Added line 
    OPEN transaction_cursor; 
    v_updated := 0; 
    LOOP 
    FETCH transaction_cursor INTO v_tidno, v_code, v_move; 
    EXIT WHEN transaction_cursor%NOTFOUND; 
    IF v_code = 'S' THEN 
    v_updated := v_updated - v_move; -- changed v_quantity to v_updated 
    END IF; 
    IF v_code = 'R' THEN 
    v_updated := v_updated + v_move; -- changed v_quantity to v_updated 
    END IF; 
    IF v_code = 'P' THEN 
    v_updated := v_updated + v_move; -- changed v_quantity to v_updated 
    END IF; 
      END LOOP; 
    INSERT into updatedinv 
     VALUES(v_idno, v_name, v_quantity, v_updated); 
    CLOSE transaction_cursor; 
END LOOP; 
CLOSE inventory_cursor; 
+0

как owuld, которые вычтут или добавят свое начальное количество с тех пор, его не вытягивая из v_quantity –

+0

Я только что реализовал это, и он не работал, так как он не вытягивается из исходного количества –

+0

v_code = 'S' нуждается в v_quantity, остальное отлично –

1

Вы написали способ сложной моды. Вы можете использовать неявные курсоры для этой цели и избегать многого кодирования.

DECLARE 
    l_updatedinv updatedinv.updatedinv%type; 
BEGIN 
    FOR i IN (select * from inventory order by itemid) 
    LOOP 
     l_updatedinv := i.quanity; 
     FOR j IN (select * from transaction where itemid = i.itemid) 
     LOOP 
     l_updatedinv := 
      case when j.code = 'S' then l_updatedinv - j.itemsmoved 
      when j.code in ('P', 'R') then l_updatedinv + j.itemsmoved 
      end; 
     END LOOP; 
    INSERT into updatedinv 
     VALUES(i.itemid, i.itemname, i.quanity, l_updatedinv); 
    END LOOP; 
END; 
/
Смежные вопросы