我正在处理多个文件作为外部表的一部分。有什么方法可以让我在外部表中处理文件名并将其放在表中?
目前我能找到的唯一解决方案是将文件名附加到平面文件中的每条记录中,从效率的角度来看这并不理想,并且涉及修改原始数据。当然,外部表随时都知道正在处理什么文件?
我正在处理多个文件作为外部表的一部分。有什么方法可以让我在外部表中处理文件名并将其放在表中?
目前我能找到的唯一解决方案是将文件名附加到平面文件中的每条记录中,从效率的角度来看这并不理想,并且涉及修改原始数据。当然,外部表随时都知道正在处理什么文件?
我不知道有什么方法可以在访问参数中捕获文件名。作为一种解决方法,您可以使用预处理器即时附加文件名,而不是修改原始文件。如果你有两个文件,比如file_1.csv
包含a,b,1
和file_2.csv
包含c,d,2
,你可以有一个小的 shell 脚本,比如append_filename.sh
:
#!/bin/bash
while read line
do
printf "%s,%s\n" "${line}" "${1##*/}"
done < $1
您可以通过直接调用脚本来验证它是否有帮助:
$ ./append_filename.sh file_1.csv
a,b,1,file_1.csv
然后,您可以定义外部表以通过子句调用它,preprocessor
例如:
create table e42 (
col1 varchar2(10),
col2 varchar2(10),
col3 number,
filename varchar2(30)
)
organization external (
type oracle_loader
default directory d42
access parameters (
records delimited by newline
preprocessor 'append_filename.sh'
fields terminated by ','
)
location ('file_1.csv', 'file_2.csv')
);
Table E42 created.
然后自动拾取文件名:
select * from e42;
COL1 COL2 COL3 FILENAME
---------- ---------- ---------- ------------------------------
a b 1 file_1.csv
c d 2 file_2.csv
我已经删除了目录路径,因此您只能看到文件名 - 如果您愿意,您可以保留完整路径,但这可能不是必需的,并且可能会向只能查询表的人透露操作系统详细信息。注意安全指南;我在这里通过对所有内容使用一个目录来保持简单,但是您应该将预处理器放在其他地方。当然,这是假设 Unix-y 平台或 GNU 工具;如果您使用的是 Windows,那么批处理文件应该可以实现类似的操作。
对于大文件,这种逐行读取的方法相对较慢;在我的平台上,附加文件名的 150 万行测试文件花费了大约 80 秒。其他内置工具会更快;这个版本sed
对于同一个文件只需要一秒钟多一点的时间:
#!/bin/bash
sed -e 's!$!,'"${1##*/}"'!' $1
您可以尝试其他替代方案,例如awk
;您可能需要测试一些以查看在您的环境中最有效(或足够快)的方法。
您可能能够从all_external_locations
DDL 中提取该数据。它包含创建表时指定的目录名称和位置参数。