【问题标题】:Writing output of query to .xlsx from a stored procedure in SQL Developer从 SQL Developer 中的存储过程将查询输出写入 .xlsx
【发布时间】:2023-03-10 00:19:01
【问题描述】:

我需要用将输出 .xlsx 文件的代码替换当前在 SQL Developer 中创建过程的过程,以将查询的输出写入 CSV。我已经对该主题进行了一些粗略的研究,但答案似乎超出了我的想象。

我试图模仿我在 google/stack overflow 上找到的解决方案,但无济于事。

CSV 程序示例:

create or replace PROCEDURE EXAMPLE_FILE_CSV AS
  CURSOR c_data IS
                       ‘QUERY HERE’;

  v_file  UTL_FILE.FILE_TYPE;
BEGIN
  v_file := UTL_FILE.FOPEN(location     => 'EXTRACT_DIR',
                           filename     => 'EXAMPLE_FILE.CSV',
                           open_mode    => 'w',
                           max_linesize => 32767);
  FOR cur_rec IN c_data LOOP
    UTL_FILE.PUT_LINE(v_file,
                      cur_rec.COL1   || ',' ||
                      cur_rec.COL2    || ',' ||
                      cur_rec.COL3      || ',' ||
                      cur_rec.COL4      || ',' ||
                      cur_rec.COL5 || ',' ||
                      cur_rec.COL6    ;
  END LOOP;
  UTL_FILE.FCLOSE(v_file);

EXCEPTION
  WHEN OTHERS THEN
    UTL_FILE.FCLOSE(v_file);
    RAISE;
END;

【问题讨论】:

  • 解决方案将取决于您使用的第 3 方程序。您使用哪个程序取决于数据的大小。开源选项可以很好地创建精美的 Excel 文件,但前提是行数相对较少。如果您必须导出十万行,那么只有商业软件可以处理这种大小。

标签: sql oracle plsql oracle-sqldeveloper


【解决方案1】:

您提供的示例代码使用 UTL_FILE,它只能访问/创建 Oracle 服务器上的文件。

由于您提到您当前是手动运行查询然后复制/粘贴(?)到 Excel 中,UTL_FILE 选项对您没有帮助。

现在,要将此查询数据放入本地/客户端文件,这种方法可能会让您入门 - 编写一个在 SQLPlus/SQLDeveloper 中运行的脚本并输出一个 CSV 文件,使用以下内容模板/示例。 XLSX 格式比较复杂。

myscript.sql:

SET LINES 2000
SET PAGES 0
SET TRIMSPOOL ON
SPOOL the_output.csv
SELECT col1 || ',' ||
       col2 || ',' ||
       col3 || ',' ||
       col4 || ',' ||
       col5 || ',' ||
       col6
FROM the_table
WHERE ...;
SPOOL OFF

您的另一个选择是使用 DBMS_OUTPUT.PUT_LINE,如下所示:

create or replace PROCEDURE EXAMPLE_FILE_CSV AS
  CURSOR c_data IS
SELECT col1,
       col2,
       col3,
       col4,
       col5,
       col6
FROM the_table
WHERE ...;
    BEGIN
      FOR cur_rec IN c_data LOOP
        DMBS_OUTPUT.PUT_LINE(
                          cur_rec.COL1   || ',' ||
                          cur_rec.COL2    || ',' ||
                          cur_rec.COL3      || ',' ||
                          cur_rec.COL4      || ',' ||
                          cur_rec.COL5 || ',' ||
                          cur_rec.COL6    ;
      END LOOP;
    END;
    /

要调用它,您可以在调用者脚本中执行以下操作:

SET SERVEROUTPUT ON
SET VERIFY OFF
SET LINES 2000
SET TRIMSPOOL OFF
SPOOL the_output.csv
EXEC EXAMPLE_FILE_CSV;
SPOOL OFF;

【讨论】:

  • SQLDev 有一个 CSV 脚本输出模式,你可以直接编写 SQL 并在 csv 中输出结果
【解决方案2】:

通过 plsql 使用“xls”编码,上述要求是可行的。 简而言之-我们使用plsql根据需要生成xls编码并将其保存为excel文件。

生成excel文件的基本xls编码:

<?xml version="1.0"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
 xmlns:o="urn:schemas-microsoft-com:office:office"
 xmlns:x="urn:schemas-microsoft-com:office:excel"
 xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
 xmlns:html="http://www.w3.org/TR/REC-html40">
 <Worksheet ss:Name="Sheet1">
  <Table>
   <Row>
    <Cell><Data ss:Type="String">cell data</Data></Cell> 
    .........
   </Row>
   ........
  </Table>
 </Worksheet>
......
</Workbook>

方法是使用数据库中的值相应地生成编码。

示例:

考虑表格:

ROLL_NO NAME            AGE
01      student no 1    15

以下plsql代码将为此表记录生成excel表

declare
cursor c1 is select * from student_tbl;
l_xls_code varchar2(4000);
begin
l_xls_code:= CHR(60)||'?xml version='||CHR(34)||'1.0'||CHR(34)||'?'||CHR(62)||CHR(12)||
CHR(60)||'Workbook xmlns='||CHR(34)||'urn:schemas-microsoft-com:office:spreadsheet'||CHR(34)||'
 xmlns:o='||CHR(34)||'urn:schemas-microsoft-com:office:office'||CHR(34)||'
 xmlns:x='||CHR(34)||'urn:schemas-microsoft-com:office:excel'||CHR(34)||'
 xmlns:ss='||CHR(34)||'urn:schemas-microsoft-com:office:spreadsheet'||CHR(34)||'
 xmlns:html='||CHR(34)||'http://www.w3.org/TR/REC-html40'||CHR(34)|| CHR(62) ||
 CHR(60)||'Worksheet ss:Name='||CHR(34)||'Student Data'||CHR(34)|| CHR(62) ||
  CHR(60)||'Table'|| CHR(62)||
   CHR(60)||'Row'|| CHR(62)|| 
    CHR(60)||'Cell'|| CHR(62)||CHR(60)||'Data ss:Type='||CHR(34)||'String'||CHR(34)|| CHR(62)||'Roll No.'||CHR(60)||'/Data'|| CHR(62)|| CHR(60)||'/Cell'|| CHR(62) ||
    CHR(60)||'Cell'|| CHR(62)||CHR(60)||'Data ss:Type='||CHR(34)||'String'||CHR(34)|| CHR(62)||'Name'||CHR(60)||'/Data'|| CHR(62)||CHR(60)||'/Cell'|| CHR(62) ||
    CHR(60)||'Cell'|| CHR(62)||CHR(60)||'Data ss:Type='||CHR(34)||'String'||CHR(34)|| CHR(62)||'Age'||CHR(60)||'/Data'|| CHR(62)||CHR(60)||'/Cell'||CHR(62) ||
   CHR(60) ||'/Row'|| CHR(62);

-- dynamically having values from the table into the excel sheet
For rec in c1
loop
l_xls_code:= l_xls_code||
 CHR(60)||'Row'|| CHR(62)|| 
    CHR(60)||'Cell'|| CHR(62)||CHR(60)||'Data ss:Type='||CHR(34)||'String'||CHR(34)|| CHR(62)||rec.roll_no||CHR(60)||'/Data'|| CHR(62)|| CHR(60)||'/Cell'|| CHR(62) ||
    CHR(60)||'Cell'|| CHR(62)||CHR(60)||'Data ss:Type='||CHR(34)||'String'||CHR(34)|| CHR(62)||rec.name||CHR(60)||'/Data'|| CHR(62)||CHR(60)||'/Cell'|| CHR(62) ||
    CHR(60)||'Cell'|| CHR(62)||CHR(60)||'Data ss:Type='||CHR(34)||'String'||CHR(34)|| CHR(62)||rec.age||CHR(60)||'/Data'|| CHR(62)||CHR(60)||'/Cell'||CHR(62) ||
   CHR(60) ||'/Row'|| CHR(62);
end loop;



l_xls_code:= l_xls_code|| CHR(60)||'/Table'||CHR(62) ||
 CHR(60)||'/Worksheet'||CHR(62)|| 
CHR(60)||'/Workbook'||CHR(62);


dbms_output.put_line(l_xls_code);

end;

上面的代码显示了输出。这将是可以以“.xls”格式存储在文件中的xml编码 这将仅通过 Excel 工作表打开

此文件将包含表中的数据。 在上面提到的例子中,数据是通过游标获取的,用于动态生成代码。 类似地,字体、单元格颜色、单元格宽度等样式可以通过plsql动态定义,并可以根据需要编码到文件中。

通常这个变量是一个clob、lob变量(因为在实时场景中这个xml编码会非常大),可以作为附件发送,或者在服务器位置创建一个文件。

类似的方法可以通过 unix 脚本来完成 - 让 sql 会话根据需要生成 xls 编码并将它们假脱机在一个文件中

【讨论】:

    猜你喜欢
    • 2011-06-07
    • 2021-12-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-16
    • 2023-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多