我有几个用于将文件数据读入数据库的外部表,每个表都用于特定的文件规范。
对于单一格式的文件,通过将表指向新的默认目录和新文件名来重复使用该表。这工作正常,除了我现在需要动态更改 BADFILE、LOGFILE 和 DISCARDFILE 参数,同时保持其余访问参数不变。
有没有一种直接的方法可以做到这一点,而不必重新指定所有其他访问参数(列转换文件分隔符等)?
我有几个用于将文件数据读入数据库的外部表,每个表都用于特定的文件规范。
对于单一格式的文件,通过将表指向新的默认目录和新文件名来重复使用该表。这工作正常,除了我现在需要动态更改 BADFILE、LOGFILE 和 DISCARDFILE 参数,同时保持其余访问参数不变。
有没有一种直接的方法可以做到这一点,而不必重新指定所有其他访问参数(列转换文件分隔符等)?
不幸的是,如果不重新指定其他访问参数,就无法仅更改 BADFILE、LOGFILE 和 DISCARDFILE 参数。
对于它的价值以及将来发现这个问题的任何人,我最终解决了以下问题:
选择外部表并在其访问参数上使用 REGEXP_REPLACE 以用我提供的新值替换与 BADFILE、LOGFILE 和 DISCARDFILE 及其关联值匹配的访问参数 BLOB 的部分。
CURSOR external_table_cur(
cp_external_table IN VARCHAR2,
cp_new_log_dir IN VARCHAR2,
cp_log_file IN VARCHAR2
)
IS
SELECT table_name,
REGEXP_REPLACE(
access_parameters,
<REGEX PATTERN>,
cp_new_log_dir||':'''||LOWER(cp_log_file),
1,
0,
'i'
) AS new_access_params
FROM all_external_tables
WHERE table_name = UPPER(cp_external_table);
然后我使用动态 SQL 来更改外部表并提供新的访问参数。
-- Point external table to new file, directory and access params
EXECUTE IMMEDIATE(
'ALTER TABLE '
|| p_table_name
|| ' DEFAULT DIRECTORY '
|| p_directory
|| ' LOCATION ('''
|| p_filename
|| ''') '
|| ' ACCESS PARAMETERS ('
|| TO_CHAR(new_access_params)
|| ')'
);
这并不理想,我最终不得不重新指定所有访问参数,但使用 REGEX(并完全测试输出)意味着该过程不会太痛苦或太慢。
从 Oracle 12cR2 开始,您可以覆盖查询中外部表的参数。
SELECT 语句的 EXTERNAL MODIFY 子句修改外部表参数。
您可以在 EXTERNAL MODIFY 子句中覆盖外部表的以下子句:
默认目录
地点
访问参数
拒绝限制
您可以在单个查询中修改多个子句。可以为 LOCATION 和 REJECT LIMIT 指定绑定变量,但不能为 DEFAULT DIRECTORY 或 ACCESS PARAMETERS 指定绑定变量。
例如:
SELECT *
FROM tab_ext EXTERNAL MODIFY (
ACCESS PARAMETERS (
BADFILE temp_dir_2:'some_tab_ext_%a_%p.bad'
LOGFILE temp_dir_2
DISCARDFILE temp_dir_2
)
);
您可以更改ACCESS PARAMETERS
子句,而其余部分保持不变。请参阅此处http://download.oracle.com/docs/cd/B28359_01/server.111/b28310/tables013.htm#i1007591
请注意,据我所知,如果您只想更改 BADFILE,您仍然必须重复访问参数中的所有内容。
例如:
ALTER TABLE ext_table
ACCESS PARAMETERS
(
records delimited by newline
badfile admin_bad_dir:'empxt%a_%p.bad'
logfile admin_log_dir:'empxt%a_%p.log'
fields terminated by ','
missing field values are null
( field1, field2 )
);