从表中的一系列数字中获取范围,并将所有范围存储在PLSQL/Oracle表单中的字符串变量中
我有一个表,其中包含一系列数字1,2,3,4,5,11,12,13,14,151011010103104105510511512513515516517。 我需要一个PL/SQL函数,这样我就可以获得范围,然后将所有范围存储在一个字符串变量中,格式如下。 “1-5、11-15、101-105、510-517” 我已经得到了一个在SQL*Plus中生成rages的代码,但它在PL/SQL和表单中不起作用。程序如下:从表中的一系列数字中获取范围,并将所有范围存储在PLSQL/Oracle表单中的字符串变量中,oracle,plsql,oracleforms,oraclereports,Oracle,Plsql,Oracleforms,Oraclereports,我有一个表,其中包含一系列数字1,2,3,4,5,11,12,13,14,151011010103104105510511512513515516517。 我需要一个PL/SQL函数,这样我就可以获得范围,然后将所有范围存储在一个字符串变量中,格式如下。 “1-5、11-15、101-105、510-517” 我已经得到了一个在SQL*Plus中生成rages的代码,但它在PL/SQL和表单中不起作用。程序如下: SQL> SET SERVEROUTPUT ON SQL> D
SQL> SET SERVEROUTPUT ON
SQL> DECLARE
2 v_list VARCHAR2(100);
3 BEGIN
4 SELECT listagg(RANGE, ',') WITHIN GROUP(
5 ORDER BY min_num)
6 INTO v_list
7 FROM
8 (SELECT MIN(num) min_num,
9 MIN(num)
10 ||'-'
11 || MAX(num) range
12 FROM
13 (SELECT num, num-Row_Number() over(order by num) AS rn FROM t
14 )
15 GROUP BY rn
16 );
17 dbms_output.put_line(v_list);
18 END;
19 /
1-3,5-7,10-12,20-20
如前所述,由于输出是一个字符串列表,因此可以在varchar2变量中声明并存储输出
您可以创建一个过程,并将整个逻辑放入其中
比如说,
设置
SQL> CREATE TABLE t AS
2 SELECT *
3 FROM
4 ( WITH data(num) AS
5 ( SELECT 1 FROM dual
6 UNION
7 SELECT 2 FROM dual
8 UNION
9 SELECT 3 FROM dual
10 UNION
11 SELECT 5 FROM dual
12 UNION
13 SELECT 6 FROM dual
14 UNION
15 SELECT 7 FROM dual
16 UNION
17 SELECT 10 FROM dual
18 UNION
19 SELECT 11 FROM dual
20 UNION
21 SELECT 12 FROM dual
22 UNION
23 SELECT 20 FROM dual
24 )
25 SELECT * FROM DATA);
Table created.
程序
SQL> CREATE OR REPLACE
2 PROCEDURE p_get_list
3 AS
4 v_list VARCHAR2(100);
5 BEGIN
6 SELECT listagg(RANGE, ',') WITHIN GROUP(
7 ORDER BY min_num)
8 INTO v_list
9 FROM
10 (SELECT MIN(num) min_num,
11 MIN(num)
12 ||'-'
13 || MAX(num) range
14 FROM
15 (SELECT num, num-Row_Number() over(order by num) AS rn FROM t
16 )
17 GROUP BY rn
18 );
19 dbms_output.put_line(v_list);
20 END;
21 /
Procedure created.
SQL> SET SERVEROUTPUT ON
SQL> BEGIN
2 p_get_list;
3 END;
4 /
1-3,5-7,10-12,20-20
PL/SQL procedure successfully completed.
测试用例
SQL> CREATE OR REPLACE
2 PROCEDURE p_get_list
3 AS
4 v_list VARCHAR2(100);
5 BEGIN
6 SELECT listagg(RANGE, ',') WITHIN GROUP(
7 ORDER BY min_num)
8 INTO v_list
9 FROM
10 (SELECT MIN(num) min_num,
11 MIN(num)
12 ||'-'
13 || MAX(num) range
14 FROM
15 (SELECT num, num-Row_Number() over(order by num) AS rn FROM t
16 )
17 GROUP BY rn
18 );
19 dbms_output.put_line(v_list);
20 END;
21 /
Procedure created.
SQL> SET SERVEROUTPUT ON
SQL> BEGIN
2 p_get_list;
3 END;
4 /
1-3,5-7,10-12,20-20
PL/SQL procedure successfully completed.
您只需在Oracle表单中调用该过程。如果我想得到相反的结果,即缺少4-4、8-9、13-19,那么在上述查询中需要什么类型的更改。@HayatMuhammad请参见