oracle-database.net-coredapperclobxmltype

C# / Dapper passing XML CLOB to Oracle stored procedure causes LPX-00210


I am working on a bulk loading program that needs to load between 10K and 30K rows into multiple tables. The approach taken is to send in a large XML file to a stored procedure. This stored procedure does an INSERT/SELECT from XMLTABLE to load the table.

When the stored procedure is called from SQL Developer with the following XML, it runs fine:

<NMFC_CTL_STG>
<row><cust>CSA</cust><itemNbr>001010</itemNbr><sub>00</sub><seqNbr>0</seqNbr><status></status><effectiveDate>1995-08-26</effectiveDate><expirationDate></expirationDate></row>
</NMFC_CTL_STG>

When the C# client generates the above XML, saves it into a Unicode string that is placed into a Dapper OracleClob as a byte[], and then call the stored procedure, the following error happens:

C# code:

using var connection = InvocationHelper.GetConnection();
var parameters = new OracleDynamicParameters();
var clobData = new OracleClob(connection as OracleConnection);

clobData.Write(bytes, 0, bytes.Length);

parameters.Add("pi_nmfc_data", bytes, OracleDbType.Clob, ParameterDirection.Input);

connection.Execute(procedureName, parameters, commandType: CommandType.StoredProcedure);

Error

Error: ORA-31011: XML parsing failed
ORA-19213: error occurred in XML processing at lines 1
LPX-00210: expected '<' instead of 'S'
ORA-06512: at "SYS.XMLTYPE", line 272
ORA-06512: at "RATES_PBLC.NMFC_IMPORTS", line 244
ORA-06512: at line 1

Line 244 of RATES_PBLC.NMFC_IMPORTS is

l_nmfc_xml_blob := xmltype(pi_nmfc_data);

I simply cannot figure out the S it is finding. I did look at the binary array and saw that the first two bytes are 255,254, which is the Byte Order Mark (BOM). I tried stripping that off and still got the same error. I tried changing the encoding to UTF-8 and the stored procedure didn't like that one bit. I did see something about the issue being the line breaks, so I removed those and still get the same error.

Any suggestions on what is going here?


Solution

  • You are creating an OracleClob object, writing some data into it from a byte array bytes, and then using bytes as the value of the parameter in your call to parameters.Add(...).

    Did you perhaps mean to use clobData instead of bytes as the value of the parameter?

    The error message you are getting is because the string System.Byte[] (i.e. what you get when you call .ToString() on a byte array) is being sent to the stored procedure. I verified this by writing a stored procedure that called raise_application_error with the procedure parameter in the message, and this is what was in the error message. Also, I can reproduce your error running select xmltype('System.Byte[]') from dual in SQL*Plus.

    Incidentally, you don't show us how you created bytes in your app, but on my system I needed to create it using Encoding.GetEncoding("UTF-16LE").GetBytes(...);. That may be an artefact of how my Oracle database (18c XE) is set up, though.