我不知道有什么方法可以在访问参数中捕获文件名。作为一种解决方法,您可以使用预处理器即时附加文件名,而不是修改原始文件。如果你有两个文件,比如包含a,b,1 的file_1.csv 和包含c,d,2 的file_2.csv,你可以有一个小的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
然后您可以定义您的外部表以通过the preprocessor clause 调用它,例如:
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
我已经删除了目录路径,因此您只能看到文件名 - 如果您愿意,您可以保留完整路径,但这可能不是必需的,并且可能会向只能查询表的人透露操作系统详细信息。注意the security guidelines;我在这里通过对所有内容使用一个目录来保持简单,但是您应该将预处理器放在其他地方。当然,这是假设 Unix-y 平台或 GNU 工具;如果您使用的是 Windows,那么批处理文件应该可以实现类似的操作。
这种逐行读取的方法对于大文件会比较慢;在我的平台上,附加文件名的 150 万行测试文件花费了大约 80 秒。其他内置工具会更快;这个带有sed 的版本对于同一个文件只需要一秒钟多一点的时间:
#!/bin/bash
sed -e 's!$!,'"${1##*/}"'!' $1
您也可以尝试其他选择,例如awk;您可能需要测试一些,看看哪种方法在您的环境中效果最好(或足够快)。