2012-09-27 21 views
5

Estoy tratando de actualizar un valor en un MS Access DB (* .mdb) usando OleDB en C#. Nada de lujo, excepto que necesito elegir la fila por un valor binario, un VARBINARY(4).Usar una columna binaria como criterio de comparación

ingenuamente pensé que UPDATE MYTABLE SET VALUE= 'new' WHERE BINVALUE=01020304; funcionaría. Pero no es así intentos alternativos fueron:

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

Usando CAST resultados en un syntax error exception: missing operator.

Usando CONVERT resultados en excepción: Undefined function 'CONVERT' in expression.

El número de filas afectadas, en int result, es siempre cero. El uso de UPDATE MYTABLE SET VALUE= 'new' WHERE VALUE= old; funciona, pero a veces afectará a más de una fila.

Al intentar y no encontrar la forma de eludir la comprobación BINVALUE Noté que no debería usar comas árabes (') alrededor de los valores en la cláusula WHERE. UPDATE MYTABLE SET VALUE= 'new' WHERE VALUE='old'; NO funciona, mientras que UPDATE MYTABLE SET VALUE= 'new' WHERE VALUE=old; funciona.

Usando MS consulta produce diferentes resultados relativos a las comas árabe:

UPDATE MYTABLE SET VALUE='new' WHERE BINVALUE='01020304' ejecuta, pero no tiene efecto.

UPDATE MYTABLE SET VALUE='new' WHERE BINVALUE=01020304 da como resultado el mensaje de error "Error de sintaxis en el número en la expresión de consulta 'BINVALUE = 01020304'."

No puedo reproducir el mensaje de error "La columna BINVALUE no se puede usar en los criterios". que mencioné en los comentarios.

El uso de otras columnas para identificar la fila deseada no funciona, ya que la mayoría de los valores son los mismos. Curiosamente, BINVALUE sirve como la clave principal.

Además de eso, no tengo permitido cambiar el esquema DB, ya que una aplicación heredada lo necesita exactamente de esa manera.

Según la entrada de gloomy.penguin, supongo que hay un problema con el tipo de conversión/coincidencia en la cláusula WHERE. Esto lleva a la pregunta de cómo se realiza la conversión/conversión en OleDB o Access, ya que el operador CAST parece ser conocido, pero CONVERT no lo es. Mi conjetura sería que CAST tiene otra sintaxis que en SQL estándar por cualquier razón.

¿Alguna sugerencia, cómo se puede hacer que esta consulta de actualización funcione?

Ésta es mi simplificada código de ejemplo:

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

Estoy seguro de que ha visto esto durante la búsqueda, pero por las dudas: http://msdn.microsoft.com/en-us/library/ms188362.aspx –

+0

No tengo nada configurado para probar y prueba cosas Por alguna razón, los valores no son iguales en la consulta sql final. Entonces, tal vez sean las citas en su lugar o quizás el valor no se esté convirtiendo o emitiendo correctamente. No he trabajado con un binvalue antes ... pero el problema es que los valores (el valor almacenado y el valor utilizado para la comparación where) no son realmente iguales por algún motivo. –

+0

@ gloomy.penguin Tienes razón, lo he visto. Considero que no es aplicable ya que se refiere a SQL Server y estoy tratando de consultar un MS Access DB. Además, no funciona. ;-) –

Respuesta

0

me di cuenta de una manera de resolver el problema de la conversión de tipos que he tenido que hacer frente. Aparentemente no es posible usar la sintaxis SQL, pero usando un comando con parámetros.

En lugar de:

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

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

tuve que usar:

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

Por supuesto que sería más limpio para agregar todos los parámetros de esta manera.Lo omití para resaltar la parte importante.

Para leer más, un ejemplo de cómo leer y escribir imágenes como datos binarios a una base de datos en la C# helper blog.

Cuestiones relacionadas