2012-09-27 20 views
5

Sto tentando di aggiornare un valore in un MS Access DB (* .mdb) utilizzando OleDB in C#. Niente di speciale, tranne che ho bisogno di scegliere la riga da un valore binario, un VARBINARY(4).Utilizzo di una colonna binaria come criterio di confronto

Ingenuamente ho pensato che UPDATE MYTABLE SET VALUE= 'new' WHERE BINVALUE=01020304; avrebbe funzionato. Ma non è così. tentativi alternativi sono stati:

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

Utilizzando CAST risultati in un syntax error exception: missing operator.

Uso CONVERT risultati in eccezione: Undefined function 'CONVERT' in expression.

Il numero di righe interessate, in int result, è sempre zero. L'utilizzo di UPDATE MYTABLE SET VALUE= 'new' WHERE VALUE= old; funziona, ma a volte colpisce più di una riga.

Durante il tentativo e non riuscendo a trovare un modo per aggirare il controllo di BINVALUE ho notato che non si dovrebbero usare le virgole arabe (') attorno ai valori nella clausola WHERE. UPDATE MYTABLE SET VALUE= 'new' WHERE VALUE='old'; non funziona mentre UPDATE MYTABLE SET VALUE= 'new' WHERE VALUE=old; funziona.

Utilizzando Microsoft Query produce diversi risultati riguardanti le virgole arabo:

UPDATE MYTABLE SET VALUE='new' WHERE BINVALUE='01020304' esegue, ma non ha alcun effetto.

UPDATE MYTABLE SET VALUE='new' WHERE BINVALUE=01020304 genera il messaggio di errore "Errore di sintassi nel numero nell'espressione di query 'BINVALUE = 01020304'."

Non riesco a riprodurre il messaggio di errore "Colonna BINVALUE non può essere utilizzato nei criteri." di cui ho parlato nei commenti.

L'utilizzo di altre colonne per identificare la riga desiderata non funziona, poiché la maggior parte dei valori sono uguali. Stranamente, BINVALUE funge da chiave primaria.

Oltre a ciò, non sono autorizzato a modificare lo schema del database, in quanto un'applicazione legacy ha bisogno esattamente in quel modo.

In base all'ingresso di gloomy.penguin, si presume che ci sia un problema con il tipo casting/matching nella clausola WHERE. Questo porta alla domanda su come casting/conversione viene eseguita in OleDB o Access poiché l'operatore CAST sembra essere noto, ma CONVERT non lo è. La mia ipotesi sarebbe che CAST ha un'altra sintassi rispetto allo standard SQL per qualsiasi ragione.

Qualche suggerimento, come è possibile far funzionare questa query di aggiornamento?

Questo è il mio ridotta codice di esempio:

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

Sono sicuro che l'hai visto durante la ricerca, ma per ogni evenienza: http://msdn.microsoft.com/en-us/library/ms188362.aspx –

+0

Non ho impostato nulla per testare e prova cose Per qualche motivo i valori non sono uguali nella query sql finale. Quindi forse sono le virgolette nel tuo dove o forse il valore non viene convertito o castato correttamente. Non ho mai lavorato con un valore binalico prima ... ma il problema è che i valori (il valore memorizzato e il valore utilizzato per il confronto in oggetto) non sono realmente uguali per qualche motivo. –

+0

@ gloomy.penguin Hai ragione, l'ho visto. Ritengo che non sia applicabile in quanto si riferisce a SQL Server e sto tentando di eseguire una query su un database MS Access. Inoltre non funziona. ;-) –

risposta

0

ho trovato un modo per risolvere il problema di casting di tipo I hanno dovuto affrontare. Apparentemente non è possibile usare la sintassi SQL, ma usando un comando con parametri.

Invece di:

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

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

ho dovuto usare:

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

Naturalmente sarebbe più pulito di aggiungere tutti i parametri in questo modo.Ho omesso quello per evidenziare la parte importante.

Per ulteriori letture, un esempio di come leggere e scrivere immagini come dati binari su un DB su C# helper blog.

Problemi correlati