Plsql 显示包含VARRAY列的记录
我有一个返回记录的函数。 记录的一列是VARRAY。 有人能告诉我怎么显示这条记录吗?(我的问题与VARRAY列有关Plsql 显示包含VARRAY列的记录,plsql,record,varray,Plsql,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" "
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;
这可能取决于您希望它的外观和显示介质(文本文件、交互式网页等),但一种方法可能是以逗号分隔的列表形式列出电话号码
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\u customer\u details
功能的期望
(顺便说一句,除非你必须这样做,否则最好不要将标识符用双引号括起来。)这可能取决于你希望它的外观以及显示介质(文本文件、交互式网页等),但一种方法可能是将电话号码列为逗号分隔的列表
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\u customer\u details
功能的期望
(顺便说一句,除非您必须这样做,否则最好不要用双引号括起标识符。)
函数调用是:
select * from table(SHOW_DETAILS.SHOW_CUSTOMER_DETAILS(101));
函数调用是:
select * from table(SHOW_DETAILS.SHOW_CUSTOMER_DETAILS(101));
我发现的另一个解决方案(不使用流水线)是: 定义对象类型
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));
我发现的另一个解决方案(不使用流水线)是: 定义对象类型
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));
我希望结果显示为“每行一条信息”。在枚举的情况下,您的解决方案完全匹配。对于表解决方案,我发现:另一种方法可能是控件中断报告。如何生成该报告将取决于显示介质。该函数用于培训目的我希望显示结果“每行一条信息“。在枚举的情况下,您的解决方案非常匹配。对于表解决方案,我发现:另一种可能是控件中断报告。如何构建该报告将取决于显示媒体。该函数用于培训目的,应该可以工作。但是,如果一次获取所有行,我认为它不需要是流水线函数(每个客户ID大概没有那么多行)。我只想让它返回数组。使用PIPELINED是因为SQL中没有定义记录类型的表。当然
t_cust_det
是表类型吗?只需使用函数returnv_return
,没有管道。是的,它是记录表。不同之处在于数据收集的方式。在您的情况下,所有电话号码都是s选中,在一行中“连接”,用逗号分隔。在我的例子中,每个电话号码都是在一个单独的行上选择的。如果有3个电话号码,select语句将返回3行(每个电话号码在其自己的行上);其余的值正在重复。这应该可以。但是,如果您一次获取所有行(并且每个客户ID大概没有那么多行),我认为不需要使用流水线函数。我只想让它返回数组。使用PIPELINED是因为SQL中没有定义记录类型的表。当然t_cust_det
是表类型吗?只需使用函数returnv_return
,没有管道。是的,它是记录表。不同之处在于数据收集的方式。在您的情况下,所有电话号码都是s选中,在一行中“连接”,用逗号分隔。在我的例子中,每个电话号码都是在一个单独的行中选择的。如果有3个电话号码,select语句将返回3行(每个电话号码在其自己的行上);其余的值将重复。