2012-10-11 109 views
2

如何使用items表顯示數據庫中的所有記錄?我當前的查詢顯示項目894的信息。我嘗試使用循環,但沒有運氣。pl/sql嵌套循環

我有兩個表,庫存和itemid。其中,itemid具有料品號和說明,而庫存表具有料品的信息,例如尺寸,顏色,價格和庫存量。

set serveroutput on 
DECLARE 
    current_item number(8);  
    totalvalue  number(8,2); 
    description  varchar2(50); 
    item_id   number(3); 


    CURSOR Inventory_Info IS  
     SELECT 
     itemsize 
     ,color 
     ,curr_price 
     ,qoh 
     ,curr_price*qoh as Total 
    FROM inventory 
    WHERE itemid=Current_item; 



BEGIN 

    current_item:=894; 
    totalvAlue:=0; 


    SELECT 
    itemdesc, itemid   
     INTO description, item_id 
    FROM item 
     WHERE itemid=current_item; 

    DBMS_OUTPUT.PUT_LINE('Item ID: ' || TO_CHAR(item_id) || ' Item Description: ' || description); 

    OPEN Inventory_Info; 
    LOOP 
      Fetch Inventory_Info INTO Inventory_rocord; 
      EXIT WHEN Inventory_Info%NOTFOUND; 

    DBMS_OUTPUT.PUT_LINE('Size: ' || Inventory_record.itemsize); 
    DBMS_OUTPUT.PUT_LINE('Color: ' || Inventory_record.color); 
    DBMS_OUTPUT.PUT_LINE('Price: ' || Inventory_record.curr_price); 
    DBMS_OUTPUT.PUT_LINE('QOH: ' || Inventory_record.qoh); 
    DBMS_OUTPUT.PUT_LINE('Value: ' || Inventory_record.total); 

    TotalValue:=TotalValue + Inventory_record.total; 

    End Loop; 

    DBMS_OUTPUT.PUT_LINE('TOTAL VALUE: ' || TotalValue); 
Close Inventory_Info; 

    EXCEPTION 
     WHEN NO_DATA_FOUND THEN      
     DBMS_OUTPUT.PUT_LINE('No inventory for Item No. '|| current_item); 
    WHEN OTHERS THEN        
     DBMS_OUTPUT.PUT_LINE('Error Message: '|| SQLERRM); 

END; 

回答

1

您要使用單獨的SELECT..INTO來獲取itemid,但你分配itemid爲單個值,不改變這種狀況。

查看您的查詢,您可以將itemid提取移入光標&加入2個表格。您將這些項目提取到inventory_record,但我沒有看到任何地方的定義/聲明。

在這裏,我聲明一個記錄類型變量,包括您正在提取的內容,打開遊標,將細節提取到該遊標中。由於沒有明確的條件,它會執行項目&庫存表&之間的內部聯接,以獲取與聯接條件匹配的所有行。

set serveroutput ON 

DECLARE 
    TYPE inventory_rec IS RECORD (
     itemid item.itemid%TYPE, 
     itemdesc item.itemdesc%TYPE, 
     itemsize inventory.itemsize%TYPE, 
     color inventory.color%TYPE, 
     curr_price inventory.curr_price%TYPE, 
     qoh inventory.qoh %TYPE, 
     total inventory.curr_price%TYPE); -- record type to hold what cursor will be fetching 

    inventory_record INVENTORY_REC; 
    current_item  NUMBER(8); 
    totalvalue  NUMBER(8, 2); 
    description  VARCHAR2(50); 
    item_id   NUMBER(3); 

    CURSOR inventory_info IS 
     SELECT itemid, 
      itemdesc, 
      itemsize, 
      color, 
      curr_price, 
      qoh, 
      curr_price * qoh AS Total 
     FROM inventory 
      join item USING (itemid); 
-- join item & inventory, so that it shows listings for all items present in inventory 

BEGIN 

    OPEN inventory_info; 

    LOOP 
     FETCH inventory_info INTO inventory_record; 
     EXIT WHEN inventory_info%NOTFOUND; 
     dbms_output.Put_line('Current item: ' 
          || inventory_record.itemdesc); 
     dbms_output.Put_line('Size: ' 
          || inventory_record.itemsize); 
     dbms_output.Put_line('Color: ' 
          || inventory_record.color); 
     dbms_output.Put_line('Price: ' 
          || inventory_record.curr_price); 
     dbms_output.Put_line('QOH: ' 
          || inventory_record.qoh); 
     dbms_output.Put_line('Value: ' 
          || inventory_record.total); 

     totalvalue := totalvalue + inventory_record.total; 
    END LOOP; 

    dbms_output.Put_line('TOTAL VALUE: ' 
         || totalvalue); 

    CLOSE inventory_info; 
EXCEPTION 
    WHEN no_data_found THEN 
     dbms_output.Put_line('No inventory for Item No. ' 
          || current_item); 
    WHEN OTHERS THEN 
     dbms_output.Put_line('Error Message: ' 
          || SQLERRM); 
END; 
+0

這使我朝着一個好方向。我想要顯示物品ID和說明,以及與該物品ID相關聯的所有庫存信息以及物品的總價值。我發佈的查詢是這樣做的,除了我必須輸入一個id。我不想輸入一個ID,我只是想讓它顯示執行時的所有數據。你認爲可以在WHERE子句中有一個指針指向另一個指針的行嗎? – user1084561

+0

@ user1084561您不必在我的查詢中輸入一個id。它從項目表中提取所有itemid。你可以使用光標參數 – Sathya

1

如果它只是一個報告(它似乎是)。考慮使用sql*plus報告格式化命令以您希望顯示查詢的方式顯示查詢的輸出。

下面是一個例子:

SQL> create table Items(
    2 i_num number, 
    3 i_descr varchar2(101), 
    4 i_size varchar2(3), 
    5 i_price number, 
    6 i_qoh number 
    7 ); 

Table created 

SQL> create table Inventories(
    2 id number, 
    3 i_num number 
    4 ); 

Table created 

SQL> insert into items(i_num,i_size,i_price,i_qoh,i_descr) 
    2 select 1, 'S', 123, 25, 'Item_1' from dual union all 
    3 select 2, 'L', 424, 12, 'Item_1' from dual union all 
    4 select 4, 'S', 45, 54, 'Item_4' from dual union all 
    5 select 5, 'S', 78, 54, 'Item_4' from dual union all 
    6 select 6, 'S', 123, 22, 'Item_5' from dual union all 
    7 select 7, 'S', 127, 65, 'Item_5' from dual 
    8 ; 

6 rows inserted 

SQL> commit; 

Commit complete 

SQL> insert into inventories 
    2 select i_num, i_num 
    3  from items; 

6 rows inserted 

SQL> commit; 

Commit complete 

現在我們的報告:

SQL> column i_descr format a10 
SQL> column i_size format a3 
SQL> column i_price format 99999 
SQL> column i_qoh format 99999 
SQL> column value format 99999 
SQL> break on i_descr skip 2 
SQL> compute sum label 'Total: ' of value on i_descr; 

SQL> select itm.i_descr 
    2  , itm.i_size 
    3  , itm.i_price 
    4  , itm.i_qoh 
    5  , sum(i_price*i_qoh) Value 
    6 from inventories inv 
    7 join items itm on (inv.i_num = itm.i_num) 
    8 group by itm.i_num 
    9   , itm.i_descr 
10   , itm.i_size 
11   , itm.i_price 
12   , itm.i_qoh 
13 order by i_descr, i_price; 


I_DESCR I_S I_PRICE I_QOH VALUE 
---------- --- ---------- ------ ------ 
Item_1  S   123  25 3075 
      L   424  12 5088 
**********      ------ 
Total:        8163 


Item_4  L   45  54 2430 
      S   78  54 4212 
**********      ------ 
Total:        6642 


Item_5  S   123  22 2706 
      L   127  65 8255 
**********      ------ 
Total:       10961 



6 rows selected. 
4

如果我們一會兒忘了格式可以這樣做更簡單與循環光標。

set serveroutput ON 
DECLARE 
BEGIN 
    FOR item_rec IN (SELECT itemdesc, itemid   
        FROM item 
       ) LOOP 
    DBMS_OUTPUT.PUT_LINE('Item ID: ' || TO_CHAR(item_rec.itemid) 
          || ' Item Description: ' || item_rec.itemdesc);      

    FOR Inventory_record IN (SELECT itemsize 
            , color 
            , curr_price 
            , qoh 
            , curr_price*qoh AS Total 
           FROM inventory 
           WHERE itemid = item_rec.itemid 
          ) LOOP 

     DBMS_OUTPUT.PUT_LINE('Size: ' || Inventory_record.itemsize); 
     DBMS_OUTPUT.PUT_LINE('Color: ' || Inventory_record.color); 
     DBMS_OUTPUT.PUT_LINE('Price: ' || Inventory_record.curr_price); 
     DBMS_OUTPUT.PUT_LINE('QOH: ' || Inventory_record.qoh); 
     DBMS_OUTPUT.PUT_LINE('Value: ' || Inventory_record.total); 

     TotalValue:= TotalValue + Inventory_record.total; 

    END LOOP;  
    END LOOP; 
END; 
+0

來設置光標的where子句,這也是我首選的方法 – Sathya

1

不要使用嵌套查詢窗口,使用加入。數據庫非常擅長連接,並且集合操作的性能比逐行處理好得多。

另外,在大多數情況下,您不需要聲明遊標和變量。使用光標循環,讓Oracle爲您完成繁重的工作。

set serveroutput on 
DECLARE  
    totalvalue  number(8,2); 
BEGIN  
    totalvAlue:=0; 
    FOR inv_itm_rec IN (  
     SELECT itm.itemid 
      , itm.itemdesc 
      , inv.itemsize   
      , inv.color   
      ,inv.curr_price   
      ,inv.qoh   
      ,inv.curr_price*inv.qoh as Total  
     FROM inventory inv 
     JOIN item itm 
      ON itm.itemid=inv.itemid 
     ) 
    LOOP 
    DBMS_OUTPUT.PUT_LINE('ItemId: ' || inv_itm_rec.itemid); 
    DBMS_OUTPUT.PUT_LINE('Description: ' || inv_itm_rec.itemdesc); 
    DBMS_OUTPUT.PUT_LINE('Size: ' || inv_itm_rec.itemsize); 
    DBMS_OUTPUT.PUT_LINE('Color: ' || inv_itm_rec.color); 
    DBMS_OUTPUT.PUT_LINE('Price: ' || inv_itm_rec.curr_price); 
    DBMS_OUTPUT.PUT_LINE('QOH: ' || inv_itm_rec.qoh); 
    DBMS_OUTPUT.PUT_LINE('Value: ' || inv_itm_rec.total); 
    TotalValue:=TotalValue + inv_itm_rec.total; 
    END LOOP; 
    DBMS_OUTPUT.PUT_LINE('TOTAL VALUE: ' || TotalValue); 
END; 

注意,此解決方案假定埃夫裏的項目確實有一個匹配的庫存記錄。如果數據模型允許其他任何事情發生,那將是朗姆酒舊倉庫應用程序。