- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
以 Oracle 论坛中显示的示例:Generating excel(xls) using plsql ,我想从查询的数据集生成一个 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;
现在,我的匿名 block 最好是像下面这样的(请注意评论):
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
和 DBMS_SQL.DEFINE_COLUMN
。否则你可以使用 FETCH Statement而不是DBMS_SQL.FETCH_ROWS(c)
关于sql - 返回显式游标的SQL语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41281665/
SQL、PL-SQL 和 T-SQL 之间有什么区别? 谁能解释一下这三者之间的区别,并提供每一个的相关使用场景? 最佳答案 SQL 是一种对集合进行操作的查询语言。 它或多或少是标准化的,几乎所有关
这个问题已经有答案了: What is the difference between SQL, PL-SQL and T-SQL? (6 个回答) 已关闭 9 年前。 我对 SQL 的了解足以完成我的
我在数据库中有一个 USER 表。该表有一个 RegistrationDate 列,该列有一个默认约束为 GETDATE()。 使用 LINQ 时,我没有为 RegistrationDate 列提供任
我有一个可能属于以下类型的字符串 string expected result 15-th-rp 15 15/12-rp 12 15-12-th
很难说出这里问的是什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或言辞激烈,无法以目前的形式合理回答。如需帮助澄清此问题以便可以重新打开,visit the help center . 9年前关闭
我有一个存储过程(称为 sprocGetArticles),它从文章表中返回文章列表。这个存储过程没有任何参数。 用户可以对每篇文章发表评论,我将这些评论存储在由文章 ID 链接的评论表中。 有什么方
我目前正在做一个 *cough*Oracle*cough* 数据库主题。讲师介绍embedded SQL作为让其他语言(例如 C、C++)与(Oracle)数据库交互的方式。 我自己做了一些数据库工作
SQL Server 中 SQL 语句的最大长度是多少?这个长度是否取决于 SQL Server 的版本? 例如,在 DECLARE @SQLStatement NVARCHAR(MAX) = N'S
这个问题已经有答案了: Simple way to transpose columns and rows in SQL? (9 个回答) 已关闭 8 年前。 CallType
预先感谢您对此提供的任何帮助。 假设我有一个查询,可以比较跨年的数据,从某个任意年份开始,永无止境(进入 future ),每年同一时期直到最后一个完整的月份(其特点是一月数据永远不会显示至 2 月
我在数据库中有一个 USER 表。该表有一个 RegistrationDate 列,该列的默认约束为 GETDATE()。 使用 LINQ 时,我没有为 RegistrationDate 列提供任何数
下面是我试图用来检查存储过程是否不存在然后创建过程的 sql。它会抛出一个错误:Incorrect syntax near the keyword 'PROCEDURE' IF NOT EXISTS
我有一个同事声称动态 SQL 在许多情况下比静态 SQL 执行得更快,所以我经常看到 DSQL 到处都是。除了明显的缺点,比如在运行之前无法检测到错误并且更难阅读,这是否准确?当我问他为什么一直使用
来自 lobodava 的动态 SQL 查询是: declare @sql nvarchar(4000) = N';with cteColumnts (ORDINAL_POSITION, CO
使用 SQL Server 中的存储过程执行动态 SQL 命令的现实优点和缺点是什么 EXEC (@SQL) 对比 EXEC SP_EXECUTESQL @SQL ? 最佳答案 sp_executes
我有这个有效的 SQL 查询: select sum(dbos.Points) as Points, dboseasons.Year from dbo.StatLines dbos i
我正在调试一些构建成功运行的 SQL 命令的代码。 然而,在查询结束时,查询结果似乎被写入了一个文本文件。 完整的查询如下 echo SELECT DATE,DATETABLE,DATE,APPDAT
我有一些创建表的 .sql 文件(MS SQL 数据库): 表_1.sql: IF OBJECT_ID (N'my_schema.table1', N'U') IS NOT NULL DROP TAB
我写了下面的 SQL 存储过程,它一直给我错误@pid = SELECT MAX(... 整个过程是: Alter PROCEDURE insert_partyco @pname varchar(20
我在 SQL Server 2005 中有包含两列 Fruit 和 Color 的表,如下所示 Fruit Colour Apple Red Orange
我是一名优秀的程序员,十分优秀!