2016-10-31 92 views
0

我有一個返回RECORD的函數。 記錄的一列是VARRAY。 有人可以提示我如何顯示記錄嗎? (我的問題是有關VARRAY列。顯示包含VARRAY列的記錄

create or replace TYPE phone_list_typ AS VARRAY(5) OF VARCHAR2(25); 

CREATE TABLE "CUSTOMERS" 
    ("CUSTOMER_ID" NUMBER(6,0), 
    "CUST_FIRST_NAME" VARCHAR2(20 BYTE) 
    "PHONE_NUMBERS" "OE"."PHONE_LIST_TYP" , 
    "CREDIT_LIMIT" NUMBER(9,2), 
    "CUST_EMAIL" VARCHAR2(40 BYTE)); 

TYPE r_cust_det IS RECORD(CUSTOMER_ID  customers.CUSTOMER_ID%TYPE 
         , CUST_FIRST_NAME customers.CUST_FIRST_NAME%TYPE 
         , PHONE_NUMBERS customers.PHONE_NUMBERS%TYPE 
         , CREDIT_LIMIT  customers.CREDIT_LIMIT%TYPE 
         , CUST_EMAIL  customers.CUST_EMAIL%TYPE); 

CREATE OR REPLACE FUNCTION show_customer_details (n_customer_id customers.customer_id%TYPE) RETURN r_cust_det 
IS 
    v_return r_cust_det; 
BEGIN 
    SELECT CUSTOMER_ID 
     , CUST_FIRST_NAME 
     , PHONE_NUMBERS 
     , CREDIT_LIMIT 
     , CUST_EMAIL 
    INTO v_return 
    FROM CUSTOMERS 
    WHERE CUSTOMER_ID = n_customer_id; 
RETURN v_return; 
END show_customer_details; 

回答

2

這可能取決於你想如何看與顯示介質是什麼(文本文件,交互式網頁等),只有一種解釋可能是列出電話號碼爲逗號分隔的列表。

select customer_id, cust_first_name, credit_limit, cust_email 
    , listagg(p.column_value,', ') within group (order by p.column_value) as phone_numbers 
from customers c cross join table(c.phone_numbers) p 
group by customer_id, cust_first_name, credit_limit, cust_email 
order by customer_id; 

我不知道你期待什麼你的show_customer_details功能,雖然。

(順便說一句這是不括在雙標識是個好主意除非你絕對必須引用。)

+0

我要顯示 「每行一個信息」 的結果。在枚舉的情況下,您的解決方案完美匹配。對於表格解決方案,我找到了這個: – mikcutu

+0

替代方案可能是控制中斷報告。你如何構建這將取決於顯示媒體。 –

+0

該功能用於訓練目的 – mikcutu

0
CREATE OR REPLACE FUNCTION show_customer_details (n_customer_id customers.customer_id%TYPE) RETURN t_cust_det PIPELINED 
    IS 
     v_return t_cust_det; 
    BEGIN 
     SELECT t1.CUSTOMER_ID 
      , t1.CUST_FIRST_NAME 
      , t2.* 
      , t1.CREDIT_LIMIT 
      , t1.CUST_EMAIL 
     BULK COLLECT INTO v_return 
     FROM CUSTOMERS t1, table(t1.phone_numbers) t2 
     WHERE t1.CUSTOMER_ID = n_customer_id 
     AND column_value is not null; 

     FOR i IN 1 .. v_return.count 
     LOOP 
      PIPE ROW (v_return(i)); 
     END LOOP; 

    END show_customer_details; 

函數調用是:

select * from table(SHOW_DETAILS.SHOW_CUSTOMER_DETAILS(101)); 
+0

這應該工作。但是,如果你一次獲取所有的行,我認爲它不需要是一個流水線函數(並且可能每個客戶ID沒有多少行)。我只是讓它返回數組。 –

+0

PIPELINED用於SQL中沒有定義記錄類型的表。 – mikcutu

+0

當然't_cust_det'是表類型?只要函數返回'v_return'而沒有管道。 –

0

另一種解決方案,我發現,在不使用PIPELINED是:

定義一個對象類型

create or replace type customers_typ 
is object 
    (CUSTOMER_ID  number(6) 
    , CUST_FIRST_NAME varchar2(20) 
    , PHONE_NUMBERS varchar2(25) --phone_list_typ 
    , CREDIT_LIMIT  number(9, 2) 
    , CUST_EMAIL  varchar2(40) 
    ); 

定義新類型,表先前定義的對象。

create or replace type t_customers_typ is table of customers_typ; 

功能成爲

CREATE OR REPLACE FUNCTION show_customer_details (n_customer_id customers.customer_id%TYPE) RETURN t_customers_typ 
IS 
    v_return t_customers_typ; 
BEGIN 
    SELECT customers_typ(t1.CUSTOMER_ID 
     , t1.CUST_FIRST_NAME 
     , t2.column_value 
     , t1.CREDIT_LIMIT 
     , t1.CUST_EMAIL) 
    BULK COLLECT INTO v_return 
    FROM CUSTOMERS t1, table(t1.phone_numbers) t2 
    WHERE t1.CUSTOMER_ID = n_customer_id 
    AND t2.column_value is not null; 

    return v_return; 

END show_customer_details; 

該功能被稱爲相同:

select * from table(SHOW_DETAILS.SHOW_CUSTOMER_DETAILS(101));