如何将 COLLECT 与 VARCHAR2 一起使用 Oracle 10g
How to Use COLLECT with VARCHAR2 Oracle 10g
我正在尝试让 COLLECT 功能为我工作。我正在使用 10g,因此发现 LISTAGG 和 WM_CONCAT 将不起作用(无效标识符错误)。我的数据例如如下。
Order Lot
123 A23088
123 A23089
089 AABBCC
305 120848
305 CCDDYY
我需要返回的如下
Order Lot
123 A23088, A23089
089 AABBCC
305 120848, CCDDYY
使用以下命令,我收到错误:TO_STRING 是无效标识符
TO_STRING ( CAST(COLLECT(DISTINCT LOT) AS varchar2(100)) ) AS LOT
使用以下命令,我收到错误:expected CHAR "inconsistent datatypes: expected %s got %s"
TO_CHAR ( CAST(COLLECT(DISTINCT LOT) AS varchar2(100)) ) AS LOT
使用以下命令,我收到错误:预期 NUMBER "inconsistent datatypes: expected %s got %s"
COLLECT(DISTINCT WHSE_LOT)
有什么方法可以让这个功能为我工作吗?
collect function 创建一个嵌套的 table,在您的例子中是一个 table 字符串,然后您可以将其转换为特定类型 - 即定义为table 的 varchar2。您不能转换为单个字符串。
有一些著名的字符串聚合技术列表,like this one. There is one that uses collect,但您仍然需要 table 类型和一个将生成的 table 转换为定界字符串的函数.
逐字复制该示例:
CREATE OR REPLACE TYPE t_varchar2_tab AS TABLE OF VARCHAR2(4000);
/
CREATE OR REPLACE FUNCTION tab_to_string (p_varchar2_tab IN t_varchar2_tab,
p_delimiter IN VARCHAR2 DEFAULT ',') RETURN VARCHAR2 IS
l_string VARCHAR2(32767);
BEGIN
FOR i IN p_varchar2_tab.FIRST .. p_varchar2_tab.LAST LOOP
IF i != p_varchar2_tab.FIRST THEN
l_string := l_string || p_delimiter;
END IF;
l_string := l_string || p_varchar2_tab(i);
END LOOP;
RETURN l_string;
END tab_to_string;
/
使用该类型和函数,您可以执行以下操作:
SELECT tab_to_string(CAST(COLLECT(DISTINCT lot) AS t_varchar2_tab)) AS lot FROM ...
有趣的是,the 10g version of collect 不支持 DISTINCT
;它不会抱怨(!?),但会留下重复项。
您可以通过 the set function 传递集合以删除重复项:
SELECT tab_to_string(SET(CAST(COLLECT(DISTINCT lot) AS t_varchar2_tab))) AS lot FROM ...
10.2.0.5 中的快速演示 运行:
create table table1(order_no number, lot varchar2(10));
insert into table1 values (590288, '2016538');
insert into table1 values (590288, '2016535');
insert into table1 values (590288, '6016535');
insert into table1 values (590288, '2016535');
insert into table1 values (590288, '2016538');
SELECT order_no, tab_to_string(SET(CAST(COLLECT(DISTINCT lot) AS t_varchar2_tab))) AS LOT
FROM table1 WHERE order_no = 590288 GROUP BY order_no;
ORDER_NO LOT
---------- --------------------------------------------------
590288 2016538,2016535,6016535
我正在尝试让 COLLECT 功能为我工作。我正在使用 10g,因此发现 LISTAGG 和 WM_CONCAT 将不起作用(无效标识符错误)。我的数据例如如下。
Order Lot
123 A23088
123 A23089
089 AABBCC
305 120848
305 CCDDYY
我需要返回的如下
Order Lot
123 A23088, A23089
089 AABBCC
305 120848, CCDDYY
使用以下命令,我收到错误:TO_STRING 是无效标识符
TO_STRING ( CAST(COLLECT(DISTINCT LOT) AS varchar2(100)) ) AS LOT
使用以下命令,我收到错误:expected CHAR "inconsistent datatypes: expected %s got %s"
TO_CHAR ( CAST(COLLECT(DISTINCT LOT) AS varchar2(100)) ) AS LOT
使用以下命令,我收到错误:预期 NUMBER "inconsistent datatypes: expected %s got %s"
COLLECT(DISTINCT WHSE_LOT)
有什么方法可以让这个功能为我工作吗?
collect function 创建一个嵌套的 table,在您的例子中是一个 table 字符串,然后您可以将其转换为特定类型 - 即定义为table 的 varchar2。您不能转换为单个字符串。
有一些著名的字符串聚合技术列表,like this one. There is one that uses collect,但您仍然需要 table 类型和一个将生成的 table 转换为定界字符串的函数.
逐字复制该示例:
CREATE OR REPLACE TYPE t_varchar2_tab AS TABLE OF VARCHAR2(4000);
/
CREATE OR REPLACE FUNCTION tab_to_string (p_varchar2_tab IN t_varchar2_tab,
p_delimiter IN VARCHAR2 DEFAULT ',') RETURN VARCHAR2 IS
l_string VARCHAR2(32767);
BEGIN
FOR i IN p_varchar2_tab.FIRST .. p_varchar2_tab.LAST LOOP
IF i != p_varchar2_tab.FIRST THEN
l_string := l_string || p_delimiter;
END IF;
l_string := l_string || p_varchar2_tab(i);
END LOOP;
RETURN l_string;
END tab_to_string;
/
使用该类型和函数,您可以执行以下操作:
SELECT tab_to_string(CAST(COLLECT(DISTINCT lot) AS t_varchar2_tab)) AS lot FROM ...
有趣的是,the 10g version of collect 不支持 DISTINCT
;它不会抱怨(!?),但会留下重复项。
您可以通过 the set function 传递集合以删除重复项:
SELECT tab_to_string(SET(CAST(COLLECT(DISTINCT lot) AS t_varchar2_tab))) AS lot FROM ...
10.2.0.5 中的快速演示 运行:
create table table1(order_no number, lot varchar2(10));
insert into table1 values (590288, '2016538');
insert into table1 values (590288, '2016535');
insert into table1 values (590288, '6016535');
insert into table1 values (590288, '2016535');
insert into table1 values (590288, '2016538');
SELECT order_no, tab_to_string(SET(CAST(COLLECT(DISTINCT lot) AS t_varchar2_tab))) AS LOT
FROM table1 WHERE order_no = 590288 GROUP BY order_no;
ORDER_NO LOT
---------- --------------------------------------------------
590288 2016538,2016535,6016535