以Oracle论坛中显示的示例:使用plsql生成excel(xls),我想从查询的数据集中生成一个excel文件。
此处提供的示例有效。但是,我遇到了一些挑战:
VARCHAR2
4000个字符的限制。我提出的内容如下:
包装定义:
create or replace package tabletoexcel
as
PROCEDURE run_query(p_fh IN UTL_FILE.FILE_TYPE
, p_cur IN SYS_REFCURSOR);
PROCEDURE start_workbook (p_fh IN UTL_FILE.FILE_TYPE);
PROCEDURE end_workbook (p_fh IN UTL_FILE.FILE_TYPE);
PROCEDURE start_worksheet(p_fh IN UTL_FILE.FILE_TYPE
, p_sheetname IN VARCHAR2);
PROCEDURE end_worksheet (p_fh IN UTL_FILE.FILE_TYPE);
PROCEDURE set_date_style (p_fh IN UTL_FILE.FILE_TYPE);
end tabletoexcel;
create or replace package body tabletoexcel
as
PROCEDURE run_query(p_fh UTL_FILE.FILE_TYPE
, p_sql IN VARCHAR2) IS
v_v_val VARCHAR2(4000);
v_n_val NUMBER;
v_d_val DATE;
v_ret NUMBER;
c NUMBER;
d NUMBER;
col_cnt INTEGER;
f BOOLEAN;
rec_tab DBMS_SQL.DESC_TAB;
col_num NUMBER;
BEGIN
c := DBMS_SQL.OPEN_CURSOR;
-- parse the SQL statement
DBMS_SQL.PARSE(c, p_sql, DBMS_SQL.NATIVE);
-- start execution of the SQL statement
d := DBMS_SQL.EXECUTE(c);
-- get a description of the returned columns
DBMS_SQL.DESCRIBE_COLUMNS(c, col_cnt, rec_tab);
-- bind variables to columns
FOR j in 1..col_cnt
LOOP
CASE rec_tab(j).col_type
WHEN 1 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_v_val,4000);
WHEN 2 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_n_val);
WHEN 12 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_d_val);
ELSE
DBMS_SQL.DEFINE_COLUMN(c,j,v_v_val,4000);
END CASE;
END LOOP;
-- Output the column headers
UTL_FILE.PUT_LINE(gv_file_type,'<ss:Row>');
FOR j in 1..col_cnt
LOOP
UTL_FILE.PUT_LINE(gv_file_type,'<ss:Cell>');
UTL_FILE.PUT_LINE(gv_file_type,'<ss:Data ss:Type="String">'||rec_tab(j).col_name||'</ss:Data>');
UTL_FILE.PUT_LINE(gv_file_type,'</ss:Cell>');
END LOOP;
UTL_FILE.PUT_LINE(gv_file_type,'</ss:Row>');
-- Output the data
LOOP
v_ret := DBMS_SQL.FETCH_ROWS(c);
EXIT WHEN v_ret = 0;
UTL_FILE.PUT_LINE(gv_file_type,'<ss:Row>');
FOR j in 1..col_cnt
LOOP
CASE rec_tab(j).col_type
WHEN 1 THEN DBMS_SQL.COLUMN_VALUE(c,j,v_v_val);
UTL_FILE.PUT_LINE(gv_file_type,'<ss:Cell>');
UTL_FILE.PUT_LINE(gv_file_type,'<ss:Data ss:Type="String">'||v_v_val||'</ss:Data>');
UTL_FILE.PUT_LINE(gv_file_type,'</ss:Cell>');
WHEN 2 THEN DBMS_SQL.COLUMN_VALUE(c,j,v_n_val);
UTL_FILE.PUT_LINE(gv_file_type,'<ss:Cell>');
UTL_FILE.PUT_LINE(gv_file_type,'<ss:Data ss:Type="Number">'||to_char(v_n_val)||'</ss:Data>');
UTL_FILE.PUT_LINE(gv_file_type,'</ss:Cell>');
WHEN 12 THEN DBMS_SQL.COLUMN_VALUE(c,j,v_d_val);
UTL_FILE.PUT_LINE(gv_file_type,'<ss:Cell ss:StyleID="OracleDate">');
UTL_FILE.PUT_LINE(gv_file_type,'<ss:Data ss:Type="DateTime">'||to_char(v_d_val,'YYYY-MM-DD"T"HH24:MI:SS')||'</ss:Data>');
UTL_FILE.PUT_LINE(gv_file_type,'</ss:Cell>');
ELSE
DBMS_SQL.COLUMN_VALUE(c,j,v_v_val);
UTL_FILE.PUT_LINE(gv_file_type,'<ss:Cell>');
UTL_FILE.PUT_LINE(gv_file_type,'<ss:Data ss:Type="String">'||v_v_val||'</ss:Data>');
UTL_FILE.PUT_LINE(gv_file_type,'</ss:Cell>');
END CASE;
END LOOP;
UTL_FILE.PUT_LINE(gv_file_type,'</ss:Row>');
END LOOP;
DBMS_SQL.CLOSE_CURSOR(c);
END run_query;
PROCEDURE start_workbook (p_fh UTL_FILE.FILE_TYPE) IS
BEGIN
UTL_FILE.PUT_LINE(gv_file_type,'<?xml version="1.0"?>');
UTL_FILE.PUT_LINE(gv_file_type,'<ss:Workbook xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">');
END start_workbook;
PROCEDURE end_workbook (p_fh UTL_FILE.FILE_TYPE) IS
BEGIN
UTL_FILE.PUT_LINE(gv_file_type,'</ss:Workbook>');
END end_workbook;
--
PROCEDURE start_worksheet(p_fh UTL_FILE.FILE_TYPE
, p_sheetname IN VARCHAR2) IS
BEGIN
UTL_FILE.PUT_LINE(gv_file_type,'<ss:Worksheet ss:Name="'||p_sheetname||'">');
UTL_FILE.PUT_LINE(gv_file_type,'<ss:Table>');
END start_worksheet;
PROCEDURE end_worksheet (p_fh UTL_FILE.FILE_TYPE) IS
BEGIN
UTL_FILE.PUT_LINE(gv_file_type,'</ss:Table>');
UTL_FILE.PUT_LINE(gv_file_type,'</ss:Worksheet>');
END end_worksheet;
--
PROCEDURE set_date_style (p_fh UTL_FILE.FILE_TYPE) IS
BEGIN
UTL_FILE.PUT_LINE(gv_file_type,'<ss:Styles>');
UTL_FILE.PUT_LINE(gv_file_type,'<ss:Style ss:ID="OracleDate">');
UTL_FILE.PUT_LINE(gv_file_type,'<ss:NumberFormat ss:Format="dd/mm/yyyy\ hh:mm:ss"/>');
UTL_FILE.PUT_LINE(gv_file_type,'</ss:Style>');
UTL_FILE.PUT_LINE(gv_file_type,'</ss:Styles>');
END set_date_style;
end tabletoexcel;
现在,我的匿名阻止最好是如下所示 (请注意注释) :
declare
l_fh UTL_FILE.FILE_TYPE;
l_directory VARCHAR2(30) := 'EMPLOYEE_FILE_DIR';
l_filename VARCHAR2(30) := 'myfile.xls';
l_sql_statement VARCHAR2(4000);
Cursor emp_cur (p_emp_no varchar2
,p_payroll_id number
,p_bg_id number)
is
select *
from table_a
where employee_number = nvl(p_emp_no, employee_number)
and payroll_id = nvl(p_payroll_id, payroll_id);
and business_group_id = p_bg_id
-- This is the Really really long query but i just placed Table_A for Sample Purposes
BEGIN
l_fh := UTl_file.FOPEN(upper(l_directory),l_filename,'w',32767);
tabletoexcel.start_workbook (l_fh);
tabletoexcel.set_date_style (l_fh);
tabletoexcel.start_worksheet(l_fh, 'EMP');
tabletoexcel.run_query(emp_cur('1', 2, 3));
-- I'm sure this won't work, but i would like to pass something simple as this.
tabletoexcel.end_worksheet (l_fh);
tabletoexcel.end_workbook (l_fh);
UTl_file.FCLOSE(l_fh);
END;
是否可以将显式游标定义传递给DBMS_SQL
包?我在考虑一个返回显式游标的SQL语句的内置函数将解决此问题。也许是基准光标?
是的,您可以使用DBMS_SQL.TO_CURSOR_NUMBER函数来实现。您的过程将如下所示:
PROCEDURE run_query(p_cur IN OUT SYS_REFCURSOR) IS
...
BEGIN
c := DBMS_SQL.TO_CURSOR_NUMBER(p_cur);
-- get a description of the returned columns
DBMS_SQL.DESCRIBE_COLUMNS(c, col_cnt, rec_tab);
...
然后,您必须这样称呼它:
declare
l_cur SYS_REFCURSOR;
BEGIN
OPEN l_cur FOR
select *
from table_a
where employee_number = nvl(p_emp_no, employee_number)
and payroll_id = nvl(p_payroll_id, payroll_id);
and business_group_id = p_bg_id
...;
tabletoexcel.run_query(l_cur);
OPEN
FOR
语句允许CLOB
作为语句,因此在大小方面没有实际限制。
由于您在设计时不知道将选择哪一列(至少我认为是这样),因此无法摆脱DBMS_SQL.DESCRIBE_COLUMNS
and
DBMS_SQL.DEFINE_COLUMN
。否则,您可以使用FETCH语句代替DBMS_SQL.FETCH_ROWS(c)
本文向大家介绍详解Oracle隐式游标和显式游标,包括了详解Oracle隐式游标和显式游标的使用技巧和注意事项,需要的朋友参考一下 游标是什么?就是在内存开辟的一块临时存储空间。 1.Oracle隐式游标 1.1Oracle有常用的哪些隐式游标 1.2 Oracle隐式游标演示 因此,我们所有都数据库的操作都是存在游标的。 -------------------------------------
问题内容: 起初我想注意到英语不是我的母语,无论我希望我们不会误会 我在Android上编写了简单的应用程序,发现了一个问题,也解决了该问题,但是无论如何,我都想了解为什么会这样。 我创建了一个sql表: 并以这种方式将数据放入其中: 现在..一切正常,我使用此应用程序进行了验证,可以存储的值正确。 不过,当我尝试使用1得到错误的值2)获得日期值时,它的负数(例如-1004124) 因此,我尝试用
问题内容: 在SQL Server中,是否可以使用存储过程在插入一些值的表中返回标识列的值?例如,如果我们在表中插入数据,则使用存储过程: 表TBL 用户ID整数,身份,自动递增 名称varchar 用户名varchar 密码varchar 因此,如果我运行存储过程插入一些值,例如: 我该如何返回此插入将发生的值。我需要其他一些操作的UserID值,有人可以解决吗? 问题答案:
我知道之前有人问过这个问题,但我还是希望有人能帮我。我使用meteorchef的基本模板。 从ScoreTotal.js在用户界面/容器目录我做: 在服务器/出版物中,我有: 当我console.log结果时,我看到聚合有效,但我得到错误“发布函数返回非光标数组” 感谢您的帮助!
问题内容: 我正在开发一个短信应用程序,我试图从每次对话中获取最新的短信。 这是我的SQL语句: 我在SQLite Expert中运行了查询,并且得到了正确的响应: 但是,当我在应用程序中运行它时,我得到: 这是我的桌子 这是我的Datamanipulator类: 问题答案: 使用时,结果的每一行对应于原始表的多行。这些结果的计算有三种可能性: 具有聚合函数的列类似于或计算组中所有行的值; 子句中
主要内容:隐式游标,显式游标在本章中,我们将讨论和学习中的游标。 Oracle创建一个称为上下文区域的内存区域,用于处理SQL语句,它包含处理该语句所需的所有信息; 例如,处理的行数等。 游标是指向此上下文区域的指针。通过游标控制上下文区域,游标保存SQL语句返回的行(一个或多个)。 游标所在的行集称为活动集。 可以命名一个游标,以便在程序中引用它来获取和处理SQL语句返回的行,一次处理一个(行)。PL/SQL中有两种类型的