编写一个 function/procedure 将大约 150k 行合并为一个并将其作为输出发送以便能够从 UI 下载
Write a function/procedure to combine around 150k rows into one and send it as output to be able to download from UI
我想就执行下面提到的场景的最佳方法获得一些意见。我只是在这里寻找替代的最佳方法,而不是调试错误。
我有一个 select 语句,它产生大约 150K 行和大约 10 列。我需要用制表符分隔符连接列,然后遍历每一行并将它们组合成一行。此列值正在使用函数调用并从 UI.
下载
当前方法:
编写一个流水线函数以将其作为 clob 输出并使用它从 UI.
下载
TYPE OUT_REC_CSV_TYP IS RECORD
( object_status VARCHAR2 ( 4000 ) ,
extract_csv CLOB ) ;
TYPE OUT_REC_CSV_TABTYP IS TABLE OF OUT_REC_CSV_TYP;
FUNCTION GET_CSV_EXTRACT (P_DATE_REPORTED IN VARCHAR2,
P__USER_ID IN NUMBER DEFAULT NULL)
RETURN OUT_REC_CSV_TABTYP
PIPELINED
IS
V_OUT_REC OUT_REC_CSV_TYP;
V_OUT_REC_EMPTY OUT_REC_CSV_TYP;
BEGIN
V_OUT_REC := V_OUT_REC_EMPTY;
V_OUT_REC.OBJECT_STATUS := NULL; --- ADDING HEADER
SELECT 'COLUMN_A' || CHR (9) || 'COLUMN_B' AS extract_csv --have around 15 columns
INTO V_OUT_REC.extract_csv
FROM DUAL;
FOR i IN (SELECT 'COLUMN_A' || CHR (9) || 'COLUMN_B' AS extract_csv
FROM (WITH
TABLE_A AS (SELECT * FROM table_1),
TABLE_B AS (SELECT * FROM table_2)
SELECT COLUMN_A, COLUMN_B
FROM TABLE_A, TABLE_B
WHERE TABLE_A.COLUMN_NAME = TABLE_B.COLUMN_NAME))
LOOP
V_OUT_REC.extract_csv :=
V_OUT_REC.extract_csv || CHR (10) || i.extract_csv;
END LOOP;
PIPE ROW (V_OUT_REC);
RETURN;
END GET_CSV_EXTRACT;
select extract_csv from TABLE(PACKAGE_NAME.GET_CSV_EXTRACT('04/19/2021','1'));
我可能措辞有误。
预期输出:所有行合并为一个,由新行分隔
COL_A COL_B COL_C COL_D COL_E
155189 测试测试测试ABCD
127557 测试测试测试ABCD
....... 说大约 150K 行合并
这种方法有时会抛出错误,并在尝试下载此 clob 值文本文件几次后起作用。
(150K 行) * (10 列) 在一行中?那是你在说什么?谁能理解其中写的内容(注意 TAB 作为列分隔符,以及可能的 NULL 值)。
另一方面,您发布的代码看起来每一行都各占一行;这个:
V_OUT_REC.extract_csv := V_OUT_REC.extract_csv || CHR (10) || i.extract_csv;
我可能是错的,但我会说你的 words 与你的 code.
因此,换一种方法怎么样? SQL*Plus 及其 spool
命令。像这样:
SQL> set linesize 100
SQL> set pagesize 0
SQL> set colsep " " --> this is (double quotes) (pressed TAB on keyboard) (double quotes)
SQL> spool test.txt
SQL> select * from dept;
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
SQL> spool off;
就这么简单。
或者,如果它必须是存储过程,我宁愿考虑创建文件的 UTL_FILE
。但是,这种方法需要访问一个目录(通常驻留在数据库服务器上)。
SQL> declare
2 l_handle utl_file.file_type;
3 l_delim varchar2(20) := chr(9); -- TAB character
4 begin
5 l_handle := utl_file.fopen('EXT_DIR',
6 'test.txt',
7 'w');
8
9 for cur_r in (select deptno, dname, loc
10 from dept)
11 loop
12 utl_file.put_line(l_handle, cur_r.deptno || l_delim ||
13 cur_r.dname || l_delim ||
14 cur_r.loc);
15 end loop;
16
17 utl_file.fclose(l_handle);
18 exception
19 when others then
20 utl_file.fclose(l_handle);
21 raise;
22 end;
23 /
PL/SQL procedure successfully completed.
SQL> $type c:\temp\test.txt --> because c:\temp is where EXT_DIR directory points to
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
SQL>
我想就执行下面提到的场景的最佳方法获得一些意见。我只是在这里寻找替代的最佳方法,而不是调试错误。
我有一个 select 语句,它产生大约 150K 行和大约 10 列。我需要用制表符分隔符连接列,然后遍历每一行并将它们组合成一行。此列值正在使用函数调用并从 UI.
下载当前方法: 编写一个流水线函数以将其作为 clob 输出并使用它从 UI.
下载TYPE OUT_REC_CSV_TYP IS RECORD
( object_status VARCHAR2 ( 4000 ) ,
extract_csv CLOB ) ;
TYPE OUT_REC_CSV_TABTYP IS TABLE OF OUT_REC_CSV_TYP;
FUNCTION GET_CSV_EXTRACT (P_DATE_REPORTED IN VARCHAR2,
P__USER_ID IN NUMBER DEFAULT NULL)
RETURN OUT_REC_CSV_TABTYP
PIPELINED
IS
V_OUT_REC OUT_REC_CSV_TYP;
V_OUT_REC_EMPTY OUT_REC_CSV_TYP;
BEGIN
V_OUT_REC := V_OUT_REC_EMPTY;
V_OUT_REC.OBJECT_STATUS := NULL; --- ADDING HEADER
SELECT 'COLUMN_A' || CHR (9) || 'COLUMN_B' AS extract_csv --have around 15 columns
INTO V_OUT_REC.extract_csv
FROM DUAL;
FOR i IN (SELECT 'COLUMN_A' || CHR (9) || 'COLUMN_B' AS extract_csv
FROM (WITH
TABLE_A AS (SELECT * FROM table_1),
TABLE_B AS (SELECT * FROM table_2)
SELECT COLUMN_A, COLUMN_B
FROM TABLE_A, TABLE_B
WHERE TABLE_A.COLUMN_NAME = TABLE_B.COLUMN_NAME))
LOOP
V_OUT_REC.extract_csv :=
V_OUT_REC.extract_csv || CHR (10) || i.extract_csv;
END LOOP;
PIPE ROW (V_OUT_REC);
RETURN;
END GET_CSV_EXTRACT;
select extract_csv from TABLE(PACKAGE_NAME.GET_CSV_EXTRACT('04/19/2021','1'));
我可能措辞有误。 预期输出:所有行合并为一个,由新行分隔 COL_A COL_B COL_C COL_D COL_E 155189 测试测试测试ABCD 127557 测试测试测试ABCD ....... 说大约 150K 行合并
这种方法有时会抛出错误,并在尝试下载此 clob 值文本文件几次后起作用。
(150K 行) * (10 列) 在一行中?那是你在说什么?谁能理解其中写的内容(注意 TAB 作为列分隔符,以及可能的 NULL 值)。
另一方面,您发布的代码看起来每一行都各占一行;这个:
V_OUT_REC.extract_csv := V_OUT_REC.extract_csv || CHR (10) || i.extract_csv;
我可能是错的,但我会说你的 words 与你的 code.
因此,换一种方法怎么样? SQL*Plus 及其 spool
命令。像这样:
SQL> set linesize 100
SQL> set pagesize 0
SQL> set colsep " " --> this is (double quotes) (pressed TAB on keyboard) (double quotes)
SQL> spool test.txt
SQL> select * from dept;
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
SQL> spool off;
就这么简单。
或者,如果它必须是存储过程,我宁愿考虑创建文件的 UTL_FILE
。但是,这种方法需要访问一个目录(通常驻留在数据库服务器上)。
SQL> declare
2 l_handle utl_file.file_type;
3 l_delim varchar2(20) := chr(9); -- TAB character
4 begin
5 l_handle := utl_file.fopen('EXT_DIR',
6 'test.txt',
7 'w');
8
9 for cur_r in (select deptno, dname, loc
10 from dept)
11 loop
12 utl_file.put_line(l_handle, cur_r.deptno || l_delim ||
13 cur_r.dname || l_delim ||
14 cur_r.loc);
15 end loop;
16
17 utl_file.fclose(l_handle);
18 exception
19 when others then
20 utl_file.fclose(l_handle);
21 raise;
22 end;
23 /
PL/SQL procedure successfully completed.
SQL> $type c:\temp\test.txt --> because c:\temp is where EXT_DIR directory points to
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
SQL>