如何在插入工作时更新 BLOB 列,错误 ORA-00932
How to Update a BLOB column, error ORA-00932, while Insert works
我无法更新 BLOB 字段,但插入有效,请参见下面的代码。
我的猜测是,它与将一个BLOB值存储在许多记录中的问题有关,涉及复制大数据。
就我而言,我知道只会更新一条记录,但 Oracle 可能认为可能需要更新多条记录。使用 Insert 时,保证只涉及 1 条记录,但使用 Update 时并不总是如此。现在我该如何解决这个问题?
注意:Where 子句中的 ArtNr 字段是具有唯一索引的主键。
顺便说一句,我很苦恼,网上有很多Insert BLOB的代码示例,但是我找不到一个Update BLOB的代码示例。
using Oracle.DataAccess.Client;//needs reference to Oracle.DataAccess.dll
using Oracle.DataAccess.Types; //OracleBlob
public static bool StoreBlobImage(OracleConnection conn, string ArtNr, byte[] bImageJpg)
{
bool Ok = false;
#if true // this is what I need, but does not work
string Sql = "update MyTable set Image = :Image where ArtNr = :ArtNr";
#else // this works
string Sql = "insert into MyTable (ArtNr, Image) values (:ArtNr, :Image)";
#endif
using (OracleCommand cmd = new OracleCommand(Sql, conn))
{
//cmd.Connection = conn;
//cmd.CommandType = CommandType.Text;
cmd.Parameters.Add("ArtNr", OracleDbType.Varchar2, 8).Value = ArtNr;
#if false // tried method 1
cmd.Parameters.Add("Image", OracleDbType.Blob).Value = bImageJpg;
#else // now trying method 2
OracleParameter blobParameter = new OracleParameter();
blobParameter.OracleDbType = OracleDbType.Blob;
blobParameter.ParameterName = "Image";
blobParameter.Value = bImageJpg;
blobParameter.Direction = ParameterDirection.Input;
blobParameter.IsNullable = true;
cmd.Parameters.Add(blobParameter);
#endif
try
{
conn.Open();
cmd.ExecuteNonQuery(); // ORA-00932: inconsistent datatypes: expected - got BLOB
}
catch (Exception TheException)
{
}// debug breakpoint
}
return Ok;
}
当我读到您的 post 时,我真的以为您是在想象事情。出于好奇,我试了一下,惊奇的是,这个错误真的出现了。
有个好消息。我四处寻找,发现了这个:
How can I update data in CLOB fields using a >> prepared query << with ODP (Oracle.DataAccess)?
事实证明,当使用带有 LOB 的更新语句时,必须首先在参数中声明 LOB。考虑到这一点,我遇到了与您的代码相同的错误,但这非常有效:
public static bool StoreBlobImage(OracleConnection conn, string ArtNr, byte[] bImageJpg)
{
bool Ok = false;
string Sql = "update MyTable set Image = :Image where ArtNr = :ArtNr";
using (OracleCommand cmd = new OracleCommand(Sql, conn))
{
cmd.Parameters.Add("Image", OracleDbType.Blob).Value = bImageJpg;
cmd.Parameters.Add("ArtNr", OracleDbType.Varchar2, 8).Value = ArtNr;
try
{
cmd.ExecuteNonQuery();
}
catch (Exception TheException)
{
}
}
return Ok;
}
切换参数即可
我对那个原始问题的问题和答案表示赞赏(在这种情况下是同一个人)。
你是对的,网上很少有关于 Oracle 中 BLOB 更新的帮助。
好问题。感觉今天学到了东西
-- 编辑--
根据 OP 的建议,根据上面引用的同一线程,还有另一个修复程序可以避免重新排列参数的必要性。我的猜测是,如果您要更新多个 LOB,这也可能会派上用场。
切换 BindByName
属性 似乎也解决了问题:
cmd.BindByName = true;
我无法更新 BLOB 字段,但插入有效,请参见下面的代码。
我的猜测是,它与将一个BLOB值存储在许多记录中的问题有关,涉及复制大数据。
就我而言,我知道只会更新一条记录,但 Oracle 可能认为可能需要更新多条记录。使用 Insert 时,保证只涉及 1 条记录,但使用 Update 时并不总是如此。现在我该如何解决这个问题?
注意:Where 子句中的 ArtNr 字段是具有唯一索引的主键。
顺便说一句,我很苦恼,网上有很多Insert BLOB的代码示例,但是我找不到一个Update BLOB的代码示例。
using Oracle.DataAccess.Client;//needs reference to Oracle.DataAccess.dll
using Oracle.DataAccess.Types; //OracleBlob
public static bool StoreBlobImage(OracleConnection conn, string ArtNr, byte[] bImageJpg)
{
bool Ok = false;
#if true // this is what I need, but does not work
string Sql = "update MyTable set Image = :Image where ArtNr = :ArtNr";
#else // this works
string Sql = "insert into MyTable (ArtNr, Image) values (:ArtNr, :Image)";
#endif
using (OracleCommand cmd = new OracleCommand(Sql, conn))
{
//cmd.Connection = conn;
//cmd.CommandType = CommandType.Text;
cmd.Parameters.Add("ArtNr", OracleDbType.Varchar2, 8).Value = ArtNr;
#if false // tried method 1
cmd.Parameters.Add("Image", OracleDbType.Blob).Value = bImageJpg;
#else // now trying method 2
OracleParameter blobParameter = new OracleParameter();
blobParameter.OracleDbType = OracleDbType.Blob;
blobParameter.ParameterName = "Image";
blobParameter.Value = bImageJpg;
blobParameter.Direction = ParameterDirection.Input;
blobParameter.IsNullable = true;
cmd.Parameters.Add(blobParameter);
#endif
try
{
conn.Open();
cmd.ExecuteNonQuery(); // ORA-00932: inconsistent datatypes: expected - got BLOB
}
catch (Exception TheException)
{
}// debug breakpoint
}
return Ok;
}
当我读到您的 post 时,我真的以为您是在想象事情。出于好奇,我试了一下,惊奇的是,这个错误真的出现了。
有个好消息。我四处寻找,发现了这个:
How can I update data in CLOB fields using a >> prepared query << with ODP (Oracle.DataAccess)?
事实证明,当使用带有 LOB 的更新语句时,必须首先在参数中声明 LOB。考虑到这一点,我遇到了与您的代码相同的错误,但这非常有效:
public static bool StoreBlobImage(OracleConnection conn, string ArtNr, byte[] bImageJpg)
{
bool Ok = false;
string Sql = "update MyTable set Image = :Image where ArtNr = :ArtNr";
using (OracleCommand cmd = new OracleCommand(Sql, conn))
{
cmd.Parameters.Add("Image", OracleDbType.Blob).Value = bImageJpg;
cmd.Parameters.Add("ArtNr", OracleDbType.Varchar2, 8).Value = ArtNr;
try
{
cmd.ExecuteNonQuery();
}
catch (Exception TheException)
{
}
}
return Ok;
}
切换参数即可
我对那个原始问题的问题和答案表示赞赏(在这种情况下是同一个人)。
你是对的,网上很少有关于 Oracle 中 BLOB 更新的帮助。
好问题。感觉今天学到了东西
-- 编辑--
根据 OP 的建议,根据上面引用的同一线程,还有另一个修复程序可以避免重新排列参数的必要性。我的猜测是,如果您要更新多个 LOB,这也可能会派上用场。
切换 BindByName
属性 似乎也解决了问题:
cmd.BindByName = true;