如何将CLOB参数从C#发送到Oracle存储过程

本文关键字:Oracle 存储过程 CLOB 参数 | 更新日期: 2023-09-27 18:27:43

我是新来的。我有个问题。我想在C#中执行此代码:

string XMLData = File.ReadAllText(App.FolderImport + "''" + FileName);
Command.CommandType = CommandType.StoredProcedure;
Command.CommandText = "PKG_DATA_EXCHANGE.IMPORT_DATA";
Command.Parameters.Add("pID_USER_M", OracleType.Number).Value = App.User.IdUser;
Command.Parameters.Add("pFILE_NAME", OracleType.VarChar).Value = FileName;
Command.Parameters.Add("pXMLDATA", OracleType.Clob).Value = XMLDataString;
Command.ExecuteNonQuery();

它适用于较小的XMLDataString,但如果它较大,则会出现异常CCD_ 1。

我知道它在某种程度上与CLOB问题有关,但我不知道如何解决它

我一直在这里寻找这样的问题,但我运气不好。

请提供任何帮助,链接或代码将不胜感激!

如何将CLOB参数从C#发送到Oracle存储过程

ORA-01460还有其他报告的原因:

  • 不兼容的字符集可能导致ORA-01460
  • 使用SQL Developer,试图将超过4000字节的字符串传递给绑定变量值可能会导致ORA-01460
  • 使用ODP,从10.2客户端和10.2 ODP移动到11.1客户端和11.1.0.6.10 ODP的用户报告了ORA-01460错误(这是一个错误,应该通过将ODP补丁到最新版本来修复)

根据关于bug 5872943的信息,与ODP.NET相关的ORA-01460虽然不是ODP错误,但在数据库版本11.2中仍然存在,据报告已修复。

解决方案是创建一个OracleClob对象,该对象接收Open()连接,然后我们将该值作为字节数组写入其中。

如果您使用EFContext,您可以按如下方式访问conactionString:

string connectionString = _context.Database.GetDbConnection().ConnectionString;

代码如下所示:

using OracleConnection connection = new(connectionString);
    
try
{
    connection.Open(); //required
    
    byte[] arrayByte = System.Text.Encoding.Unicode.GetBytes(audit.AuditRecord);
    OracleClob oracleClob = new (connection);
    oracleClob.Write(arrayByte, 0, arrayByte.Length);
    var parameters = new OracleParameter[]
    {
        new OracleParameter("param1", OracleDbType.Varchar2, valueParam1, ParameterDirection.Input),
        new OracleParameter("param_clob", OracleDbType.Clob, oracleClob, ParameterDirection.Input),
        new OracleParameter("p_refcursor", OracleDbType.RefCursor, ParameterDirection.Output)
    };
    OracleCommand cmd= new("SCHEMA.STORED_PROCEDURE_NAME", connection)
    {
        CommandType = CommandType.StoredProcedure,
    };
    cmd.Parameters.AddRange(parameters);
    cmd.ExecuteNonQuery();
    
    //getting the returned values
    var result = (OracleRefCursor)cmd.Parameters["p_refcursor"].Value;
    var reader = result.GetDataReader();
    reader.Read();
    // To access the returned values
    //reader.GetOracleValue(0)
    //reader.GetOracleValue(1)
    //reader.GetOracleValue(2)
}
finally
{
    connection.Close();
}