使用二进制列作为比较标准

时间:2012-09-27 14:43:20

标签: c# sql ms-access ado.net oledb

我正在尝试使用C#中的OleDB更新MS Access DB(* .mdb)中的值。没什么好看的,除了我需要用二进制值VARBINARY(4)选择行。

天真地我认为UPDATE MYTABLE SET VALUE= 'new' WHERE BINVALUE=01020304;会起作用。但事实并非如此。 另类尝试是:

UPDATE MYTABLE SET VALUE= 'new' WHERE BINVALUE='01020304';
UPDATE MYTABLE SET VALUE= 'new' WHERE BINVALUE='0x01020304';
UPDATE MYTABLE SET VALUE= 'new' WHERE BINVALUE=0x01020304;
UPDATE MYTABLE SET VALUE= 'new' WHERE BINVALUE=CAST('01020304' as VARBINARY);
UPDATE MYTABLE SET VALUE= 'new' WHERE BINVALUE=CAST(01020304 as VARBINARY);
UPDATE MYTABLE SET VALUE= 'new' WHERE BINVALUE=CAST('01020304' as VARBINARY(4));
UPDATE MYTABLE SET VALUE= 'new' WHERE BINVALUE=CAST(01020304 as VARBINARY(4));
UPDATE MYTABLE SET VALUE= 'new' WHERE BINVALUE=CONVERT(varbinary(4),'01020304');
UPDATE MYTABLE SET VALUE= 'new' WHERE CAST(BINVALUE as VARCHAR(MAX)) = CAST('01020304' as VARCHAR(MAX));
UPDATE MYTABLE SET VALUE= 'new' WHERE CAST(BINVALUE as VARCHAR(MAX)) = CAST(01020304 as VARCHAR(MAX));
UPDATE MYTABLE SET VALUE= 'new' WHERE CONVERT(VARCHAR(MAX), BINVALUE) = CONVERT(VARCHAR(MAX), '01020304');

使用CAST会产生syntax error exception: missing operator

使用CONVERT会导致异常:Undefined function 'CONVERT' in expression.

int result中受影响的行数始终为零。使用UPDATE MYTABLE SET VALUE= 'new' WHERE VALUE= old;有效,但有时会遇到多行。

尝试并且未能找到绕过检查{... 1}的方法时,我注意到你不应该在WHERE子句中的值周围使用阿拉伯语逗号(')。 <{1}}工作时BINVALUE不起作用。

使用MS Query会产生有关阿拉伯语逗号的不同结果:

UPDATE MYTABLE SET VALUE= 'new' WHERE VALUE='old';执行,但没有效果。

UPDATE MYTABLE SET VALUE= 'new' WHERE VALUE=old;会导致错误消息“查询表达式中的语法错误数'BINVALUE = 01020304'。”

我无法重现错误消息“无法在条件中使用列BINVALUE”。我在评论中提到过。

使用其他列来标识所需的行不起作用,因为大多数值都相同。奇怪的是,UPDATE MYTABLE SET VALUE='new' WHERE BINVALUE='01020304'可以作为主键。

最重要的是,我不允许更改数据库架构,因为遗留应用程序完全需要它。

根据gloomy.penguin的输入,我假设WHERE子句中的类型转换/匹配存在问题。这导致了如何在OleDB或Access中完成转换/转换的问题,因为CAST运算符似乎已知,但CONVERT不是。我的猜测是,无论出于何种原因,CAST都有另一种语法而不是标准SQL。

有任何建议,如何使此更新查询起作用?

这是我的精简示例代码:

UPDATE MYTABLE SET VALUE='new' WHERE BINVALUE=01020304

1 个答案:

答案 0 :(得分:0)

我找到了解决我一直面临的类型转换问题的方法。 显然,不可能使用SQL语法,而是使用带参数的命令。

而不是:

String cmd = @"UPDATE " + table + " SET VALUE= '" + newvalue + "'"
    + " WHERE BINVALUE= '" + ToHexString(binvalue) + "'"
    + ";";

OleDbCommand command = new OleDbCommand(cmd, connection);
int result = command.ExecuteNonQuery();

我不得不使用:

String cmd = @"UPDATE " + table + " SET VALUE= '" + newvalue + "'"
    + " WHERE BINVALUE= @binval" + ";";

OleDbCommand command = new OleDbCommand(cmd, connection);

OleDbParameter param = new OleDbParameter();
param.OleDbType = OleDbType.Binary;
param.ParameterName = "binval";
param.Value = binvalue;
command.Parameters.Add(param);

int result = command.ExecuteNonQuery();

当然以这种方式添加所有参数会更清晰。我忽略了这一点,以突出重要部分。

进一步阅读,以如何将图像作为二进制数据读写到DB的示例 在C# helper blog