我的结果如下所示
I_KEY
10001
10002
10003
10004
10005
我需要修改结果以将输出显示为
I_KEY
10001,10002,10003,10004,10005
我已经编写了oracle函数来返回聚合结果,如下所示,我的疑问是,LISTAGG是否会处理 NUMBER 类型的值?
create or replace
FUNCTION GET_I_KEY(
RETURN NUMBER
IS
TEST I_DETAILS.I_KEY%TYPE;
BEGIN
SELECT LISTAGG(I_KEY, ',') WITHIN GROUP (ORDER BY I_KEY)
INTO TEST
FROM I_DETAILS
RETURN TEST;
EXCEPTION
WHEN NO_DATA_FOUND THEN
TEST := NULL;
RETURN TEST;
END;
更新功能
create or replace
FUNCTION GET_I_KEY(
IN I_DETAILS.I_NAME%TYPE)
RETURN VARCHAR2
IS
TEST VARCHAR2(4000);
BEGIN
SELECT LISTAGG(I_KEY, ',') WITHIN GROUP (ORDER BY I_KEY)
INTO TEST
FROM I_DETAILS ID ,I_TYPE IT
WHERE ID.I_KEY = IT.I_KEY
AND ID.I_NAME = IN;
RETURN TEST;
END;
答案 0 :(得分:3)
该函数的参数遵循以下规则:
- measure_expr可以是任何表达式。度量列中的空值将被忽略。 ...
如果度量列为RAW,则返回数据类型为RAW;否则返回值为VARCHAR2。
measure_expr ,在这种情况下,您的I_KEY
列可以是数字。 (数值将隐式转换为字符串)。结果不能是数字 - 因为您没有传递RAW
数据,它将是VARCHAR
。
您发布的功能存在语法错误,您可能在发布时引入了这些错误,但由于您已将TEST
声明为数字,因此修正后会出现运行时错误(通过%TYPE
语法)。
create or replace
FUNCTION GET_I_KEY
RETURN NUMBER
IS
TEST I_DETAILS.I_KEY%TYPE;
BEGIN
SELECT LISTAGG(I_KEY, ',') WITHIN GROUP (ORDER BY I_KEY)
INTO TEST
FROM I_DETAILS;
RETURN TEST;
EXCEPTION
WHEN NO_DATA_FOUND THEN
TEST := NULL;
RETURN TEST;
END;
/
Function GET_I_KEY compiled
select get_i_key from dual;
ORA-06502: PL/SQL: numeric or value error: character to number conversion error
ORA-06512: at "MY_SCHEMA.GET_I_KEY", line 6
您需要将TEST
和函数返回类型声明为字符串。您也不需要异常处理程序 - listagg()
是一个聚合函数,因此它永远不会返回任何行;由于没有group-by子句,它总是会返回1行,如果没有数据则为null。
create or replace
FUNCTION GET_I_KEY
RETURN VARCHAR2
IS
TEST VARCHAR2(4000);
BEGIN
SELECT LISTAGG(I_KEY, ',') WITHIN GROUP (ORDER BY I_KEY)
INTO TEST
FROM I_DETAILS;
RETURN TEST;
END;
/
Function GET_I_KEY compiled
select get_i_key from dual;
GET_I_KEY
----------------------------------------
10001,10002,10003,10004,10005
如果原始数据中有重复值,并且想要从结果中删除它们,则可以使用子查询;将函数内的查询更改为:
SELECT LISTAGG(I_KEY, ',') WITHIN GROUP (ORDER BY I_KEY)
INTO TEST
FROM (
SELECT DISTINCT I_KEY
FROM I_DETAILS
);
或修改后的函数使用相同的模式:
create or replace
FUNCTION GET_I_KEY(
IN I_DETAILS.I_NAME%TYPE)
RETURN VARCHAR2
IS
TEST VARCHAR2(4000);
BEGIN
SELECT LISTAGG(I_KEY, ',') WITHIN GROUP (ORDER BY I_KEY)
INTO TEST
FROM (
SELECT DISTINCT IT.I_KEY
FROM I_DETAILS ID
JOIN I_TYPE IT
ON IT.I_KEY = ID.I_KEY
WHERE ID.I_NAME = IN
);
RETURN TEST;
END;
/
虽然加入似乎毫无意义 - 您可以只查询I_DETAILS
,除非您有孤儿关键值,这些关键值不会出现在I_TYPE
中,并且您试图将其排除在外。