【发布时间】:2011-09-13 06:34:44
【问题描述】:
IBM Informix SDK:
声明:Update mytable set myblobcolumn = ? where myid = 1;
using (IfxConnection conn = GetIfxConnection())
using (IfxCommand cmd = new IfxCommand(updateSql, conn))
{
var param = new IfxParameter("myblobcolumn", IfxType.Blob) { IsNullable = true };
cmd.Parameters.Add(param).Value = DBNull.Value
cmd.ExecuteNonQuery(); //ERROR [HY000] [Informix .NET provider][Informix]Illegal attempt to use Text/Byte host variable.
}
如果我用另一个 IfxBlob 对象更新它,它工作正常,但如果我用 DBNull.Value 更新它,我会收到错误。任何人都知道如何使用参数化更新“取消设置”blob 列?
更新:
好的,我做了一些研究,并减少了一点。
首先,我发现如果我在生成参数时显式声明IfxType,当从数据库中的空值来回切换时,.NET驱动程序在转换DBNull.Value甚至Byte[]数组时遇到问题并在数据库中有一个实际的 IfxBlob。基本上:
- 如果列包含一个值,而我希望在其中存储 null,那么我必须按如下方式对参数进行类型转换:
UPDATE mytable SET myblobcolumn = ?::byte WHERE myid = 1;。这使我可以存储DBNull.Value的值而不会出现任何错误。 - 如果该列包含一个空值并且我希望在其中存储一个实际值,那么我必须按如下方式对我的参数进行类型转换:
UPDATE mytable SET myblobcolumn = ?::blob WHERE myid = 1;。这允许我存储 IfxBlob 值。
现在,为了避免所有这些,我将 Parameter 初始化减少为仅设置 ParameterName 属性:var param = new IfxParameter { ParameterName = "myblobcolumn" }(即使这样也只是为了能够从集合中引用它,仅此而已)。这让我可以保留我的陈述,而不必对我的参数进行类型转换。
所以...我剩下以下内容:
声明:UPDATE mytable SET myblobcolumn = ? where myid = 1;
using (IfxConnection conn = GetIfxConnection())
using (IfxCommand cmd = new IfxCommand(updateSql, conn))
{
var param = new IfxParameter { ParameterName = "myblob" }
cmd.Parameters.Add(param);
var value = GetSomeValue();
if (value is Byte[])
cmd.Paremeters["myblob"].Value = GetIfxBlob(value);
else
cmd.Parameters["myblob"].Value = DBNull.Value;
//...
}
这很好用,但我认为我在 Informix .NET 驱动程序 (3.50.xC7) 中发现了一个类似于 this one 的错误。基本上,提供的链接表明发现了一个错误,该错误不允许 .NET 驱动程序在执行插入时正确使用 byte[] 数组来创建 blob。这已得到解决,因为我可以在执行 INSERT 语句时执行cmd.Parameters["myblob"].Value = new Byte[] { 0x1, 0x2 };。但是,当将 byte[] 数组用于 UPDATE 语句时,驱动程序仍然会给出异常。因此,我必须实际创建 IfxBlob 实例并使用它们而不是实际的 byte[] 数组。
如果这不是驱动程序中的错误,那么这个问题需要保持开放,以查看设置/取消设置 blob 字段的正确方法是使用 byte[] 数组进行更新。
【问题讨论】:
-
什么是sdk版本号?
-
它是哪种类型的 blob 列?字节、文本、BLOB 还是 CLOB?
-
这是一个 Blob 列。我已经更新了我的问题以更新我对此的发现。
标签: c# .net blob informix dbnull