vir*_*lea 2 sql plsql oracle11g
我正在使用外部表来从文件加载数据.这个数据有很多需要经过的处理,外部表是动态创建的,所以数据应该被加载到外部表中,然后进入全局临时表,然后删除外部表并进行处理继续临时表中的数据.临时表的结构与外部表的结构相匹配.
删除外部表正在清除全局临时表.
这一切都发生在同一个过程中,所以我不认为这是一个会话问题.
proc看起来像这样:
create or replace
PROCEDURE Upload_Data_File
(
filename IN varchar2
)
IS
can_create_table char(1) := 'Y';
ext_table_name varchar2(200) := filename;
sql_to_run varchar(5000) := '';
BEGIN
/*****************************************************************************
Create external table/load file data
*****************************************************************************/
BEGIN
ext_table_name := replace(ext_table_name, '.', '_');
ext_table_name := 'ext_' || ext_table_name;
sql_to_run := 'CREATE TABLE ' || ext_table_name || '
(
ROW1 CHAR(1 BYTE),
ROW2 CHAR(1 BYTE),
RECORD_TEXT VARCHAR2(200 BYTE),
RECORD_NUMBER NUMBER
)
ORGANIZATION EXTERNAL
(
TYPE ORACLE_LOADER
DEFAULT DIRECTORY FILE_DIRECTORY
ACCESS PARAMETERS
(
RECORDS DELIMITED BY NEWLINE
FIELDS
(
ROW1 char(1)
,ROW2 char(1)
,record_text position(3:203)
,record_number recnum
)
)
LOCATION
(
''' || filename || '''
)
)
REJECT LIMIT UNLIMITED';
EXECUTE IMMEDIATE sql_to_run;
can_create_table := 'Y';
END;
IF can_create_table = 'Y' THEN
/***************************************************************************
To avoid the use of a lot of dynamic SQL, a single statement will move
the rows from the external table to a global temp table.
***************************************************************************/
sql_to_run := 'INSERT INTO Global_File_Upload (
ROW1,
ROW2,
record_text,
record_number
)
SELECT
ROW1,
ROW2,
record_text,
record_number
FROM ' || ext_table_name;
EXECUTE IMMEDIATE sql_to_run;
/***************************************************************************
The external table is no longer needed and can be dropped
***************************************************************************/
sql_to_run := 'DROP TABLE ' || ext_table_name;
--EXECUTE IMMEDIATE sql_to_run;
/***************************************************************************
Process the records in the temp table
***************************************************************************/
END IF;
END IF;
Run Code Online (Sandbox Code Playgroud)
只要注释掉用于删除外部表的EXECUTE IMMEDIATE,该过程就会正确运行.但是如果我允许该语句运行,则临时表中没有要处理的数据.
我的赌注是将全局临时表定义为ON COMMIT DELETE ROWS
而不是ON COMMIT PRESERVE ROWS
.由于DDL像创建或删除表一样隐式提交,因此当事务结束时删除行的全局临时表将在会话中执行任何DDL时清除其数据.如果要保留数据,则需要将表定义为ON COMMIT PRESERVE ROWS
.
退一步说,这个架构似乎有问题.动态创建和删除对象几乎不是合适的解决方案.从您发布的示例中,您似乎正在删除并创建外部表,只是为了更改您正在加载的文件.最好只保留表并更改文件名
ALTER TABLE external_table_name
LOCATION( '<<new file name>>' );
Run Code Online (Sandbox Code Playgroud)
您似乎不太可能希望将数据加载到临时表中,而不是直接查询外部表.除非你在临时表上构建索引以便提高处理效率,否则临时表不会为你买任何东西.但是,来自外部文件的大多数加载只是对数据进行单次传递,以便加载到永久表中.
归档时间: |
|
查看次数: |
102 次 |
最近记录: |