我正在尝试将数据从XML文件导入Oracle中的表。我正在使用TOAD
我已经按照下面的Oracle论坛帖子进行了相同的操作: https://community.oracle.com/thread/2182669
XML文件如下(Example2.xml;与论坛中刚刚更改的名称相同):
<?xml version="1.0"?>
<ACCOUNT_HEADER_ACK>
<HEADER>
<STATUS_CODE>100</STATUS_CODE>
<STATUS_REMARKS>check</STATUS_REMARKS>
</HEADER>
<DETAILS>
<DETAIL>
<SEGMENT_NUMBER>2</SEGMENT_NUMBER>
<REMARKS>rp polytechnic</REMARKS>
</DETAIL>
<DETAIL>
<SEGMENT_NUMBER>3</SEGMENT_NUMBER>
<REMARKS>rp polytechnic administration</REMARKS>
</DETAIL>
<DETAIL>
<SEGMENT_NUMBER>4</SEGMENT_NUMBER>
<REMARKS>rp polytechnic finance</REMARKS>
</DETAIL>
<DETAIL>
<SEGMENT_NUMBER>5</SEGMENT_NUMBER>
<REMARKS>rp polytechnic logistics</REMARKS>
</DETAIL>
</DETAILS>
<HEADER>
<STATUS_CODE>500</STATUS_CODE>
<STATUS_REMARKS>process exception</STATUS_REMARKS>
</HEADER>
<DETAILS>
<DETAIL>
<SEGMENT_NUMBER>20</SEGMENT_NUMBER>
<REMARKS> base polytechnic</REMARKS>
</DETAIL>
<DETAIL>
<SEGMENT_NUMBER>30</SEGMENT_NUMBER>
</DETAIL>
<DETAIL>
<SEGMENT_NUMBER>40</SEGMENT_NUMBER>
<REMARKS> base polytechnic finance</REMARKS>
</DETAIL>
<DETAIL>
<SEGMENT_NUMBER>50</SEGMENT_NUMBER>
<REMARKS> base polytechnic logistics</REMARKS>
</DETAIL>
</DETAILS>
</ACCOUNT_HEADER_ACK>
我已经创建了我打算获取数据的目录和表:
create directory test_direc as 'C:\Documents and Settings\adeb01\Desktop'
create table xxrp_acct_details(
segment_number number,
status_code number,
status_remarks varchar2(100),
remarks varchar2(100)
);
创建表和目录后,我正在运行它:
DECLARE
acct_doc xmltype := xmltype( bfilename('test_direc','Example2.xml'), nls_charset_id('AL32UTF8') );
BEGIN
insert into xxrp_acct_details (status_code, status_remarks, segment_number, remarks)
select x.*
from xmltable(
'for $i in /ACCOUNT_HEADER_ACK/HEADER
return
for $j in $i/following-sibling::DETAILS[1]/DETAIL
return element r {$i, $j}'
passing acct_doc
columns status_code number path 'HEADER/STATUS_CODE',
status_remarks varchar2(100) path 'HEADER/STATUS_REMARKS',
segment_number number path 'DETAIL/SEGMENT_NUMBER',
remarks varchar2(100) path 'DETAIL/REMARKS'
) x
;
END;
当我运行时,我收到错误:
ORA-22285: non-existent directory or file for FILEOPEN operation
ORA-06512: at "SYS.XMLTYPE", line 296
ORA-06512: at line 3
我没有得到我做错的事。
我有一种感觉控制文件可能是一个问题,因为我没有创建任何。
=============================================== =========
在我之前的代码中,问题是连接没有正确构建。 我现在所做的是将整个XML存储到声明中的文件中,我正在调用它。 但是我遇到以下错误: ORA-06550:第14行,第19栏: PLS-00382:表达式类型错误
我改变了我的代码:
DECLARE
v_outputfile UTL_FILE.FILE_TYPE:=UTL_FILE.FOPEN('\home\apradh01\','Example2.xml','w');
BEGIN
insert into xxrp_acct_details (status_code, status_remarks, segment_number, remarks)
select x.*
from xmltable(
'for $i in /ACCOUNT_HEADER_ACK/HEADER
return
for $j in $i/following-sibling::DETAILS[1]/DETAIL
return element r {$i, $j}'
passing XMLTYPE(v_outputfile)
columns status_code number path 'HEADER/STATUS_CODE',
status_remarks varchar2(100) path 'HEADER/STATUS_REMARKS',
segment_number number path 'DETAIL/SEGMENT_NUMBER',
remarks varchar2(100) path 'DETAIL/REMARKS'
) x
;
END;
=============================================== ==
好的,所以有一些连接问题,我确定当我修改我的代码时(例如,而不是从我手动输入的文件中读取XML内容),它工作正常:
DECLARE
BEGIN
insert into xxrp_acct_details (status_code, status_remarks, segment_number, remarks)
select x.*
from xmltable(
'for $i in /ACCOUNT_HEADER_ACK/HEADER
return
for $j in $i/following-sibling::DETAILS[1]/DETAIL
return element r {$i, $j}'
passing XMLTYPE('<?xml version="1.0"?>
<ACCOUNT_HEADER_ACK>
<HEADER>
<STATUS_CODE>100</STATUS_CODE>
<STATUS_REMARKS>check</STATUS_REMARKS>
</HEADER>
<DETAILS>
<DETAIL>
<SEGMENT_NUMBER>2</SEGMENT_NUMBER>
<REMARKS>rp polytechnic</REMARKS>
</DETAIL>
<DETAIL>
<SEGMENT_NUMBER>3</SEGMENT_NUMBER>
<REMARKS>rp polytechnic administration</REMARKS>
</DETAIL>
<DETAIL>
<SEGMENT_NUMBER>4</SEGMENT_NUMBER>
<REMARKS>rp polytechnic finance</REMARKS>
</DETAIL>
<DETAIL>
<SEGMENT_NUMBER>5</SEGMENT_NUMBER>
<REMARKS>rp polytechnic logistics</REMARKS>
</DETAIL>
</DETAILS>
<HEADER>
<STATUS_CODE>500</STATUS_CODE>
<STATUS_REMARKS>process exception</STATUS_REMARKS>
</HEADER>
<DETAILS>
<DETAIL>
<SEGMENT_NUMBER>20</SEGMENT_NUMBER>
<REMARKS> base polytechnic</REMARKS>
</DETAIL>
<DETAIL>
<SEGMENT_NUMBER>30</SEGMENT_NUMBER>
</DETAIL>
<DETAIL>
<SEGMENT_NUMBER>40</SEGMENT_NUMBER>
<REMARKS> base polytechnic finance</REMARKS>
</DETAIL>
<DETAIL>
<SEGMENT_NUMBER>50</SEGMENT_NUMBER>
<REMARKS> base polytechnic logistics</REMARKS>
</DETAIL>
</DETAILS>
</ACCOUNT_HEADER_ACK>'
)
columns status_code number path 'HEADER/STATUS_CODE',
status_remarks varchar2(100) path 'HEADER/STATUS_REMARKS',
segment_number number path 'DETAIL/SEGMENT_NUMBER',
remarks varchar2(100) path 'DETAIL/REMARKS'
) x
;
END;
因此,我挑选XML数据并将其传输到表格的代码是正确的 现在唯一的问题是我应该如何传输文件名而不是手动输入XML
我觉得我们可以利用UTL_FILE来读取文件的内容,然后存储&amp;将它传递给
acct_doc xmltype := xmltype( bfilename('TEST_DIR','acct.xml'), nls_charset_id('AL32UTF8') );
任何建议......
答案 0 :(得分:1)
您使用create directory test_direc ...
创建了目录,这意味着您使用了非引用的标识符,这是好的;但这意味着它存储在数据字典中,名称大写。如果您将all_directories
视图查询为TEST_DIREC
。因此,当您将目录名称作为字符串传递时,您需要使用该大写名称:
bfilename('TEST_DIREC','Example2.xml')
除此之外,你所展示的作品;你真的不需要PL / SQL块,你可以使用普通的SQL insert语句直接在passing
子句中提供文件:
passing xmltype( bfilename('TEST_DIREC','Example2.xml'), nls_charset_id('AL32UTF8') )
这假定您指向的目录C:\Documents and Settings\adeb01\Desktop
位于运行数据库本身的同一台计算机上,并且Oracle可以看到它。您只能访问服务器上的目录,而不能访问连接到它的任何客户端 - 这是安全模型的一部分。来自the create directory
documentation:
目录对象指定服务器文件系统上的目录的别名 ...
...无论运行哪个帐户,Oracle数据库都必须具有访问该目录的操作系统权限,如果它位于您的个人帐户下,则可能不是这种情况。
如果文件当前在您的PC上并且数据库位于其他位置,则需要将文件复制到服务器 - 到Oracle有权访问的目录 - 并创建指向该服务器目录的Oracle目录对象