5

我正在尝试使用 C# 中的 OleDB 更新 MS Access DB (*.mdb) 中的值。没什么特别的,只是我需要通过二进制值 a 来选择行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');

在 a 中使用CAST结果syntax error exception: missing operator

CONVERT在异常中使用结果:Undefined function 'CONVERT' in expression.

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

在尝试并未能找到规避检查的方法时,BINVALUE我注意到您不应该在 WHERE 子句中的值周围使用阿拉伯逗号 (')。UPDATE MYTABLE SET VALUE= 'new' WHERE VALUE='old';工作时不工作UPDATE MYTABLE SET VALUE= 'new' WHERE VALUE=old;

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

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

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

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

使用其他列来标识所需的行不起作用,因为大多数值是相同的。奇怪的BINVALUE是用作主键。

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

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

有什么建议,如何使这个更新查询起作用?

这是我精简的示例代码:

static String ToHexString(Byte[] buffer)
{
    String str;
    str = BitConverter.ToString(buffer).Replace("-", string.Empty);
    return (str);
}

...

String table = "MYTABLE";
String newvalue = "new";
Byte[] binvalue = { 1, 2, 3, 4 };

String providerStr= @"Provider=Microsoft.JET.OLEDB.4.0;" + @"data source=C:\myDB.mdb";
connection = new OleDbConnection(providerStr);
connection.Open();

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

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

connection.Close();
4

1 回答 1

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();

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

如需进一步阅读,请参阅C# 助手博客上的如何将图像作为二进制数据读取和写入数据库的示例。

于 2012-10-02T10:42:59.887 回答