如何使用>>更新CLOB字段中的数据?准备好的查询<<使用ODP(Oracle.DataAccess)?

时间:2014-03-11 10:22:22

标签: c# oracle .net-3.5 odp.net clob

我正在尝试执行准备好的SQL查询,该查询更新Oracle 10g数据库(10.2.0.1)中的CLOB字段。

如果我从SQL Developer内部执行以下查询并提供占位符的值,则没有问题。但是,如果我通过OracleCommand(Oracle.DataAccess.dll,版本1.102.0.1(我认为),.NET Framework 3.5)执行它, 我收到以下错误消息。请注意,我们不使用默认的oracle客户端,因为我们需要批量插入。不幸的是,给定的ODP版本和.NET Framework版本是一项艰难的要求,我们可能不会改变它。

查询:

UPDATE master_table
SET    description = :description,
       modification_notes = :modification_notes
WHERE  master_id = :master_id;

错误:

  

ORA-00932:不一致的数据类型:预期 - 获得CLOB

进一步的信息:

参数分配如下:

var param_description = new OracleParameter(":description", OracleDbType.Clob);
param_description.Value = "Test";

我尝试了以下事项:

  • to_clob()插入SQL查询
  • 为参数分配Oracle.DataAccess.Types.OracleClob个对象。

我也发现了以下描述,但我真的希望能够保留准备好的查询。

How to insert CLOB field in Oracle using C#

是否可以通过准备好的查询来完成此操作?

我附上了一个产生错误的完整示例。 DESCRIPTIONMODIFICATION_NOTES是数据库中CLOB类型的两列。


输入数据:

  • 连接:OracleConnection到数据库
  • master_id:过滤
  • 的主键

代码:
免责声明:我手动输入以下示例,可能存在实际代码中没有的错误

var query = "UPDATE master_table " + 
            "SET description = :description " + 
            "    modification_notes = :modification_notes " +
            "WHERE master_id = :master_id";

var param_master_id = new OracleParameter(":master_id", OracleDbType.Int64);
param_master_id.Value = master_id;

var param_description = new OracleParameter(":description", OracleDbType.Clob);
param_description.Value = "Test1";

var param_master_id = new OracleParameter(":modification_notes", OracleDbType.Clob);
param_description.Value = "Test2";

IDbCommand command = new OracleCommand(query, connection);
command.parameters.Add(param_master_id);
command.parameters.Add(param_description);
command.parameters.Add(param_modification_notes);

command.ExecuteNonQuery(); // this line throws an exception

4 个答案:

答案 0 :(得分:6)

如果要按名称绑定,则需要将其设置为true。默认值是按添加的参数的顺序绑定。

cmd.BindByName = true; 

答案 1 :(得分:5)

编辑:我的答案适用于Clobs的典型使用,其大小超过32k(它们的设计目的)。如果你知道你将永远绑定少于32k字节,或者通常情况下是unicode的16k字符,你可以绑定为Varchar2,并且不必创建一个临时的高架。

-

请记住,oracle列中的LOB实际上是一个LOB定位器,一个指向实际数据的指针。在使用该Lob Locator更新CLOB列之前,需要先创建并填充临时CLOB。

在Oracle Home的ODP.NET samples目录中应该有一个LOB目录,在那里看起来sample5.cs可能是一个很好的起点。这是一个片段:

  // Set the command
  OracleCommand cmd = new OracleCommand(
    "update multimedia_tab set story = :1 where thekey = 1");
  cmd.Connection = con;
  cmd.CommandType = CommandType.Text; 

  // Create an OracleClob object, specifying no caching and not a NCLOB
  OracleClob clob = new OracleClob(con, false, false);

  // Write data to the OracleClob object, clob, which is a temporary LOB
  string str = "this is a new story";
  clob.Write(str.ToCharArray(), 0, str.Length);

  // Bind a parameter with OracleDbType.Clob
  cmd.Parameters.Add("clobdata", 
                      OracleDbType.Clob, 
                      clob, 
                      ParameterDirection.Input);

  try 
  {
    // Execute command
    cmd.ExecuteNonQuery();

答案 2 :(得分:2)

请参阅实际解决方案的已接受答案。

[编辑:前疑似答案]:
<击> 经过几天的测试和调试后,我找到了远离我考虑过的所有内容的解决方案:

显然,您需要在绑定任何其他字段之前先绑定所有Clob字段 - 即使使用实际占位符而不是使用:1:2等。

更改绑定顺序(即AddParameter调用的顺序)修复它。

答案 3 :(得分:-1)

试试这个:

  string Query3 = "  DECLARE " +
                  "str varchar2(32767); " +
                  " BEGIN " +
                  " str := '" + base64ImageRepresentationLogo + "'; " +
                  "  update map_general_settings set value=str where  DESC_AR='LOGO_IMG' ; END; ";
                    command.CommandText = Query3;
                    command.ExecuteNonQuery();