我们有一个现有的程序包,可以将数据插入存储在远程数据库(SQL Server)中的表中。以下是该软件包的摘要:
CREATE OR REPLACE PACKAGE XXMyPackage
AS
PROCEDURE GiveMyCursor;
END XXMyPackage;
/
CREATE OR REPLACE PACKAGE BODY XXMyPackage
AS
PROCEDURE GiveMyCursor IS
cursor cursor_1 is
SELECT 'really long query with a lot of joined tables' column1
, 'this is an existing code' column2
, 'i cannot modify this' column3
from dual;
BEGIN
for cursor_x in cursor_1 loop
sql_stmt := 'insert into some_remote_table (column1, column2, column3, column4, column5)'||
'values (:1, 0, :2, :3, 0) ';
EXECUTE IMMEDIATE sql_stmt
USING trim(cursor_x.column1),
trim(cursor_x.column2),
trim(cursor_x.column3);
l_count := get_records_for_insert%rowcount;
end loop;
END GiveMyCursor;
END XXMyPackage;
/
我的任务是通过在插入后将其内容转储到目录中的XLSX
文件中来为此程序包添加功能。
另外,我应该对现有代码进行很少的修改,并使代码尽可能短。
我可以通过以下修改来做到这一点(注意带有“添加的”注释的行:
CREATE OR REPLACE PACKAGE XXMyPackage
AS
TYPE refMyCursor IS REF CURSOR RETURN curMyCursor%ROWTYPE; -- added
TYPE typMyCursor IS TABLE OF curMyCursor%ROWTYPE; -- added
PROCEDURE GiveMyCursor;
END XXMyPackage;
/
CREATE OR REPLACE PACKAGE BODY XXMyPackage
AS
PROCEDURE GiveMyCursor IS
pCursor SYS_REFCURSOR; -- added
l_directory DBA_DIRECTORIES.DIRECTORY_NAME%TYPE := 'DATA_DIR'; -- added
l_filename VARCHAR2(250) := 'SAMPLE_FILENAME'; -- added
cursor cursor_1 is
SELECT 'really long query with a lot of joined tables' column1
, 'this is an existing code' column2
, 'i cannot modify this' column3
from dual;
BEGIN
for cursor_x in cursor_1 loop
sql_stmt := 'insert into some_remote_table (column1, column2, column3, column4, column5)'||
'values (:1, 0, :2, :3, 0) ';
EXECUTE IMMEDIATE sql_stmt
USING trim(cursor_x.column1),
trim(cursor_x.column2),
trim(cursor_x.column3);
l_count := get_records_for_insert%rowcount;
end loop;
/* **************** Start of added Code **************** */
-- cursor query was re-used
OPEN pCursor FOR
SELECT 'really long query with a lot of joined tables' column1
, 'this is an existing code' column2
, 'i cannot modify this' column3
from dual;
l_filename := l_filename||'_'||TO_CHAR(SYSDATE, 'DDMMYYYYHHMISS')||'.xlsx';
-- dumps the query results into an xlsx file
as_xlsx.query2sheet( p_cur => pCursor -- Uses Sys_RefCursor
, p_sheetname => l_filename -- This is where we assign the Sheet Names
, p_directory => l_directory -- Saves it into the directory
, p_filename => l_filename -- The filename of the xlsx file
);
/* **************** End of added Code **************** */
END GiveMyCursor;
END XXMyPackage;
/
注意:软件包as_xlsx
是从另一个SO帖子(Create an Excel File (.xlsx) using PL/SQL)提取的
我已经确认修改后的程序包可以工作,并且在匿名块中运行XXMyPackage.GiveMyCursor
时可以在目录中看到该文件。但是,cursor_1
非常长,已被重新用于打开SYS_REFCURSOR
pCursor
。我尝试将其缩短,以便进一步修改代码以使其:
CREATE OR REPLACE PACKAGE XXMyPackage
AS
/* **************** Start of added Code **************** */
cursor cursor_1 is
SELECT 'really long query with a lot of joined tables' column1
, 'this is an existing code' column2
, 'i cannot modify this' column3
from dual;
TYPE typMyCursor IS TABLE OF cursor_1%ROWTYPE;
/* **************** End of added Code **************** */
PROCEDURE GiveMyCursor;
END XXMyPackage;
/
CREATE OR REPLACE PACKAGE BODY XXMyPackage
AS
PROCEDURE GiveMyCursor IS
tabMyCursor typMyCursor; -- added
pCursor SYS_REFCURSOR; -- added
l_directory DBA_DIRECTORIES.DIRECTORY_NAME%TYPE := 'DATA_DIR'; -- added
l_filename VARCHAR2(250) := 'SAMPLE_FILENAME'; -- added
BEGIN
for cursor_x in cursor_1 loop
sql_stmt := 'insert into some_remote_table (column1, column2, column3, column4, column5)'||
'values (:1, 0, :2, :3, 0) ';
EXECUTE IMMEDIATE sql_stmt
USING trim(cursor_x.column1),
trim(cursor_x.column2),
trim(cursor_x.column3);
l_count := get_records_for_insert%rowcount;
end loop;
/* **************** Start of added Code **************** */
OPEN cursor_1;
FETCH cursor_1 BULK COLLECT INTO tabMyCursor;
CLOSE cursor_1;
OPEN pCursor FOR
SELECT *
FROM TABLE(tabMyCursor);
l_filename := l_filename||'_'||TO_CHAR(SYSDATE, 'DDMMYYYYHHMISS')||'.xlsx';
-- dumps the query results into an xlsx file
as_xlsx.query2sheet( p_cur => pCursor -- Uses Sys_RefCursor
, p_sheetname => l_filename -- This is where we assign the Sheet Names
, p_directory => l_directory -- Saves it into the directory
, p_filename => l_filename -- The filename of the xlsx file
);
/* **************** End of added Code **************** */
END GiveMyCursor;
END XXMyPackage;
/
但是,当我这样做时,在匿名块中运行No more data to read from socket
几秒钟后,我得到了错误XXMyPackage.GiveMyCursor
。造成此错误的原因是什么?
数据库版本:
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
PL/SQL Release 12.1.0.2.0 - Production
"CORE 12.1.0.2.0 Production"
TNS for Linux: Version 12.1.0.2.0 - Production
NLSRTL Version 12.1.0.2.0 - Production