2016-10-31 20 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

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

+0

PIPELINED использовался, поскольку в SQL не была определена таблица типа записи. – mikcutu

+0

Неужели 't_cust_det' - это тип таблицы? Просто возвращайте функцию 'v_return' без конвейера. –

0

Другим решением я нашел, без использования конвейерного является:

Определить тип объекта

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)); 

 Смежные вопросы

  • Нет связанных вопросов^_^