我正在尝试执行准备好的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#
是否可以通过准备好的查询来完成此操作?
我附上了一个产生错误的完整示例。 DESCRIPTION
和MODIFICATION_NOTES
是数据库中CLOB
类型的两列。
输入数据:
OracleConnection
到数据库 代码:
免责声明:我手动输入以下示例,可能存在实际代码中没有的错误
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
答案 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();