OR1
asked on
How can I query xml inside a blob column?
I am trying to search xml that is contained within a blob column.
My first attempt was this:
select NAME,
extractValue(GDB_USERMETAD ATA.xml, '/METADATA/CITATION/CITEIN FO/TITLE')
TITLE
from GDB_USERMETADATA;
And I got this error: ORA-00932: inconsistent datatypes: expected - got -
The following adviced from a users forum I tried this;
select NAME,
extractValue(xmltype(GDB_U SERMETADAT A.xml), '/METADATA/CITATION/CITEIN FO/TITLE')
TITLE
from GDB_USERMETADATA;
and I got this other error:
ORA-06553: PLS-306: wrong number or types of arguments in call to 'XMLTYPE'
Thanks in advance
My first attempt was this:
select NAME,
extractValue(GDB_USERMETAD
TITLE
from GDB_USERMETADATA;
And I got this error: ORA-00932: inconsistent datatypes: expected - got -
The following adviced from a users forum I tried this;
select NAME,
extractValue(xmltype(GDB_U
TITLE
from GDB_USERMETADATA;
and I got this other error:
ORA-06553: PLS-306: wrong number or types of arguments in call to 'XMLTYPE'
Thanks in advance
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
The column is a blob. Does than mean I have to export the data to another table? I was trying to do make this part of a report I could generate quickly.
Not really export it to another table but you will likely need to write your own function to convert it to a CLOB first.
sdstuber can confirm this. I don't want to take over his question.
sdstuber can confirm this. I don't want to take over his question.
yes, if the column is a blob, you need to convert it to a clob.
if the blob is bigger than 32767 bytes then you will need to call the dbms_lob.converttoclob function multiple times to copy the entire thing.
and, as slightwv suggested, it might be easiest to do that in your own function.
then you write your report like
extractValue(
xmltype(your_function(your blob_colum n)),
'/METADATA/CITATION/CITEIN FO/TITLE'
)
if the blob is bigger than 32767 bytes then you will need to call the dbms_lob.converttoclob function multiple times to copy the entire thing.
and, as slightwv suggested, it might be easiest to do that in your own function.
then you write your report like
extractValue(
xmltype(your_function(your
'/METADATA/CITATION/CITEIN
)
ASKER
Following some of your suggestions and using afunction I found in another forum I am able to query the information for one record at a time. when I try many records I get the following errors:
ORA-31020: The operation is not allowed, Reason: For security reasons, ftp and http access over XDB repository is not allowed on server side
ORA-06512: at "SYS.XMLTYPE", line 272
ORA-06512: at line 1
If i do this it works:
SELECT NAME,
EXTRACTVALUE
(XMLtype( BLOB_TO_CLOB(GDB_USERMETAD ATA.XML)), '/metadata//idinfo/citatio n/citeinfo /title') TITLE
FROM GDB_USERMETADATA
WHERE NAME = 'tl_2009_us_metdiv';
NAME,TITLE
tl_2009_us_metdiv,TIGER/Li ne Shapefile, 2009, nation, U.S., Current Metropolitan Division National
This one fails
SELECT NAME,
EXTRACTVALUE
(XMLtype( BLOB_TO_CLOB(GDB_USERMETAD ATA.XML)), '/metadata//idinfo/citatio n/citeinfo /title') TITLE
FROM GDB_USERMETADATA;
The function I am using is attached;
ORA-31020: The operation is not allowed, Reason: For security reasons, ftp and http access over XDB repository is not allowed on server side
ORA-06512: at "SYS.XMLTYPE", line 272
ORA-06512: at line 1
If i do this it works:
SELECT NAME,
EXTRACTVALUE
(XMLtype( BLOB_TO_CLOB(GDB_USERMETAD
FROM GDB_USERMETADATA
WHERE NAME = 'tl_2009_us_metdiv';
NAME,TITLE
tl_2009_us_metdiv,TIGER/Li
This one fails
SELECT NAME,
EXTRACTVALUE
(XMLtype( BLOB_TO_CLOB(GDB_USERMETAD
FROM GDB_USERMETADATA;
The function I am using is attached;
CREATE OR REPLACE FUNCTION blob_to_clob (blob_in IN BLOB)
RETURN CLOB
AS
v_clob CLOB;
v_varchar VARCHAR2 (32767);
v_start PLS_INTEGER := 1;
v_buffer PLS_INTEGER := 32767;
BEGIN
DBMS_LOB.CREATETEMPORARY (v_clob, TRUE);
FOR i IN 1 .. CEIL (DBMS_LOB.GETLENGTH (blob_in) / v_buffer)
LOOP
v_varchar :=
UTL_RAW.
CAST_TO_VARCHAR2 (DBMS_LOB.SUBSTR (blob_in, v_buffer, v_start));
DBMS_LOB.WRITEAPPEND (v_clob, LENGTH (v_varchar), v_varchar);
v_start := v_start + v_buffer;
END LOOP;
RETURN v_clob;
END blob_to_clob;
/
Per Metalink, one of the XML files has an external reference like A DTD.
Check out Doc ID 803686.1
Check out Doc ID 803686.1
ASKER
I saw it but I am trying to retrieve text elements not format the xml. Furthermore the pproblem seems to happen when I query more than one record. I don't see why I need the DTD. I will probably have to ask our DBA to contact tech support.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks to both of you I was able to complete my script. The error I was getting in the end was fixed by correcting two metadata files that had problems specifically duplicate entries.
Thanks!
Thanks!
You will probably need to write your own function to wrap the XML extract call.