我必须通过外部表读取文件,但是这个文件位于ACFS内的另一个目录中。 作为第一步,我必须移动文件 所以,我决定使用运行脚本的预处理器功能
这是我的表格(前提:所有权限都设置正确等)
CREATE TABLE EXT_FILE
( "REC" VARCHAR2(3 BYTE),
"VAL" VARCHAR2(4 BYTE),
...
)
ORGANIZATION EXTERNAL
( TYPE ORACLE_LOADER
DEFAULT DIRECTORY "ACFS_EXECDIR"
ACCESS PARAMETERS
( RECORDS DELIMITED BY NEWLINE
PREPROCESSOR ACFS_EXECDIR:'preprocess.sh'
FIELDS LDRTRIM
MISSING FIELD VALUES ARE NULL
REJECT ROWS WITH ALL NULL FIELDS
(
"REC" (1:3) CHAR(3),
"VAL" (4:7) CHAR(4),
...
)
)
LOCATION
( 'file.ftp'
)
)
REJECT LIMIT UNLIMITED ;
这个文件位于一个文件夹中,而脚本(preprocess.sh)则位于另一个文件夹中 所以我想这样做: *将文件移动到ACFS_EXECDIR目录,
所以在执行
时SELECT * FROM EXT_FILE
,'预处理'功能将执行移动文件的脚本 进入默认目录( ACFS_EXECDIR ),然后阅读
但它不起作用。因为它无法找到文件
KUP-04040: file file.ftp in ACFS_EXECDIR not found
29913. 00000 - "error in executing %s callout"
*Cause: The execution of the specified callout caused an error.
*Action: Examine the error messages take appropriate action.
所以我创建了一个空白文件只是为了传递异常并且它有效。 我认为该功能会在其他任何事情之前执行脚本,然后阅读它 当然文件不存在..
我做的另一个测试是用脚本的名称替换文件名以再次“绕过”异常。它奏效了。
LOCATION ( 'preprocess.sh')
谢谢
SCRIPT:
#!/bin/bash
#my dir
DIR_FTP='...'
DIR_ACFS='...'
/bin/mv $DIR_FTP/file.ftp $DIR_ACFS/file.ftp
/bin/cat $DIR_ACFS/file.ftp # without cat cannot view the file
答案 0 :(得分:0)
答案 1 :(得分:0)
documentation没有明确说明,但是,该文件必须已经存在。这个概念是预处理指定的文件,而不是在加载开始之前执行任意操作。
传递给预处理器脚本的参数是文件的完整操作系统路径,因此Oracle正在从目录对象的路径和位置文件名构造它 - 并且可能在执行任何其他操作之前检查它是否存在。
正如您所见,您可以通过将位置指向虚拟文件来解决此问题,并让预处理器脚本完成所有工作 - 甚至不需要将文件复制到正确的目录中因为它最终导致了它。 (这是一个好主意是另一回事;请确保您已经注意到此功能的安全警告。)
你必须抓住文件:
预处理程序将数据转换为访问驱动程序支持的记录格式,然后将转换后的记录数据写入标准输出(stdout),访问驱动程序将其作为输入读取。
文档中的一个示例是使用zcat
解压缩文件 - 标准输出;最终查看原始文件名(仍然是压缩文件)是没有意义的。