How does one upload an XML document (datum of Oracle type XMLType) into a table on an Oracle database, from a Delphi program using the DBX library?
Example on the server-side
Suppose we have a simple table with a column of type XMLType. We want to insert a new record with an XML document in it. The document, as encoded as a string, is longer than the 4000 character limit for varchar2
create global temporary table XML_UPLOADED_DOC(
DOC_ID number not null,
CONTENT XMLType not null)
on commit preserve rows;
alter table XML_UPLOADED_DOC add (
constraint XML_UPLOADED_DOC_PK primary key (DOC_ID));
create sequence XML_UPLOADED_DOC_SEQ;
create or replace trigger XML_UPLOADED_DOC_BIR
before insert on XML_UPLOADED_DOC
for each row
begin
select XML_UPLOADED_DOC_SEQ.NEXTVAL
into :new.DOC_ID
from dual;
end;
What I have tried so far
This Delphi procedure, when run ...
procedure UploadDoc( Con: TSQLConnection; const Doc: IXMLDocument);
var
Query: TSQLQuery;
Param: TParam;
begin
Query := TSQLQuery.Create( nil);
Query.SQLConnection := Con;
Query.SQL.Add( 'insert into XML_UPLOADED_DOC ');
Query.SQL.Add( '(CONTENT) values (XmlType(''<place-marker/>'')) ');
Query.SQL.Add( 'returning CONTENT into :content');
Param := Query.ParamByName('content');
Param.DataType := ftString;
Param.ParamType := ptInput;
Param.AsString := Doc.XML.Text;
Query.ExecSQL;
Query.Close;
Query.Free;
end;
... results in this error ...
ORA-22816: unsupported feature with RETURNING clause
Tool versions
The server banner returns ...
BANNER
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi
PL/SQL Release 10.2.0.4.0 - Production
CORE 10.2.0.4.0 Production
TNS for IBM/AIX RISC System/6000: Version 10.2.0.4.0 - Productio
NLSRTL Version 10.2.0.4.0 - Production
The oracle client version is 11g.
The Delphi version is Delphi XE7 + Update 1 (Version 21.0.17707.5020)
Update
I think I have worked out a solution which works for large documents and goes roughly like this: (1) Use stored procedures (and the DBX TSQLProc component) instead of TSQLQuery; (2) Create a temp table with a CLOB column, and upload the text equivalent of the document, by part-by-part after dividing the document into chunks of less than 32k characters. The oracle DBMS_LOB.WriteAppend() function can be used to build up the CLOB part by part. This method works around the driver limitations on clob size. (3) Call one last sproc to convert the clob into an XMLType instance. I will post a solution when it is polished.