L’ordine dei parametri per l’object Command del database è davvero importante?

Stavo eseguendo il debug di un codice operativo del database e ho scoperto che l’UPDATE corretto non si verificava mai, anche se il codice non falliva mai in quanto tale. Questo è il codice:

condb.Open(); OleDbCommand dbcom = new OleDbCommand("UPDATE Word SET word=?,sentence=?,mp3=? WHERE id=? AND exercise_id=?", condb); dbcom.Parameters.AddWithValue("id", wd.ID); dbcom.Parameters.AddWithValue("exercise_id", wd.ExID); dbcom.Parameters.AddWithValue("word", wd.Name); dbcom.Parameters.AddWithValue("sentence", wd.Sentence); dbcom.Parameters.AddWithValue("mp3", wd.Mp3); 

Ma dopo alcuni aggiustamenti ciò ha funzionato:

  condb.Open(); OleDbCommand dbcom = new OleDbCommand("UPDATE Word SET word=?,sentence=?,mp3=? WHERE id=? AND exercise_id=?", condb); dbcom.Parameters.AddWithValue("word", wd.Name); dbcom.Parameters.AddWithValue("sentence", wd.Sentence); dbcom.Parameters.AddWithValue("mp3", wd.Mp3); dbcom.Parameters.AddWithValue("id", wd.ID); dbcom.Parameters.AddWithValue("exercise_id", wd.ExID); 
  1. Perché è così importante che i parametri nella clausola WHERE debbano essere dati l’ultimo in caso di connessione OleDb? Avendo già lavorato con MySQL in precedenza, potevo (e di solito faccio) scrivere i parametri della clausola WHERE perché è più logico per me.

  2. L’ordine dei parametri è importante quando si esegue una query sul database in generale? Qualche problema di prestazioni o qualcosa del genere?

  3. Esiste un ordine specifico da mantenere in caso di altri database come DB2, Sqlite ecc.?

Aggiornamento: mi sono liberato di ? e includeva nomi propri con e senza @ . L’ordine è molto importante. In entrambi i casi, solo quando i parametri della clausola WHERE sono stati citati per ultimi, si è verificato l’aggiornamento effettivo. A peggiorare la situazione, in query complesse, è difficile sapere da noi stessi quale ordine è l’Access che si aspetta, e in tutte le situazioni in cui l’ordine è cambiato, la query non fa il suo dovere previsto senza avvertimenti / errori !!

All’interno di Access, un object ADODB.Command ignora i nomi dei parametri. In effetti, posso fare riferimento a un parametro che utilizza un nome falso (che non esiste nemmeno nell’istruzione SQL) e ADO non si cura. Tutto ciò che interessa è che tu fornisca i valori dei parametri nello stesso ordine in cui quei parametri appaiono nell’istruzione SQL. BTW, questo è anche quello che succede se costruisco l’istruzione SQL con ? segnaposto anziché parametri con nome.

Mentre mi rendo conto che la tua domanda riguarda C # e OleDbCommand , mi sembra che OleDbCommand di OleDbCommand stia funzionando come Access ‘ ADODB.Command . Sfortunatamente, non conosco Dot.Net … ma questa è la mia impressione. 🙂

L’ordine è importante a causa dell’uso di? segnaposto nella stringa di comando.

Se si desidera elencare i parametri in qualsiasi ordine, è meglio utilizzare parametri denominati, come @word, @sentence, ecc.

 condb.Open(); OleDbCommand dbcom = new OleDbCommand("UPDATE Word SET word=@word,sentence=@sentence,mp3=@mp3 WHERE id=@id AND exercise_id=@exercise_id", condb); dbcom.Parameters.AddWithValue("@id", wd.ID); dbcom.Parameters.AddWithValue("@exercise_id", wd.ExID); dbcom.Parameters.AddWithValue("@word", wd.Name); dbcom.Parameters.AddWithValue("@sentence", wd.Sentence); dbcom.Parameters.AddWithValue("@mp3", wd.Mp3); 

Ho fatto alcuni test con l’utilizzo di OleDbCommand e la sua raccolta di parametri contro un Access DB. L’ordinamento dei parametri è ovviamente necessario, poiché si tratta di una limitazione del provider OLE DB .NET . Ma c’è un problema che puoi incontrare quando usi i punti interrogativi come segnaposto.

Supponiamo che tu abbia una query (“stored procedure”) nel tuo Access DB simile a questa, molto semplificata qui:

 parameters prmFirstNumber Long, prmSecondNumber Long; select fullName from tblPersons where numberOfCars < prmFirstNumber And numberOfPets < prmSecondNumber And numberOfBooks beteween prmFirstNumber And prmSecondNumber 

Qui vedete che semplicemente cambiando a punti interrogativi si rompe la query.

Ho trovato però, come soluzione a questo, che puoi effettivamente usare i nomi per i parametri. Quindi puoi lasciare che la query sopra rimanga così com'è. Devi solo usare lo stesso ordine quando esegui la query. Come in questo caso, per prima cosa aggiungi il parametro prmFirstNumber e poi prmSecondNumber, quindi esegui la query.

Quando si riutilizzano i parametri, ovvero si esegue una query più volte e si impostano ogni volta nuovi valori per i parametri, è necessario chiamare il metodo di preparazione dell'object comando subito dopo aver definito i parametri. Ci sono alcuni dettagli che devono essere soddisfatti, guarda la documentazione per "preparare". Non chiamare prepara provoca strani comportamenti senza messaggi di errore che possono danneggiare il database o causare informazioni errate agli utenti.

Posso anche aggiungere che quando le query vengono memorizzate nel DB di Access con parametri specificati, come nell'esempio precedente, l'ordinamento dei parametri viene definito in modo univoco dalla sezione parametri.

Ho anche creato una routine, "retrieveDeclaredJetParametersInOrder", che popola automaticamente un object OleDbCommand con quei parametri con nome, nell'ordine corretto. Quindi il mio codice può assomigliare a questo:

 Dim cmd As New OleDbCommand("qryInAccessDB", Conn) cmd.CommandType = CommandType.StoredProcedure Conn.Open() retrieveDeclaredJetParametersInOrder(cmd) cmd.Parameters("prmOneOfTheParametersPerhapsTheLastOneDeclared").Value = 1 cmd.Parameters("prmAnotherone").Value = 20 cmd.Parameters("prmYetAnotherPerhapsTheFirstOneDeclared").Value = 300 cmd.ExecuteNonQuery() Conn.Close() 

Quindi, come vedi, posso gestirlo come se i parametri fossero nominati, e non dovrei mai preoccuparmi del loro ordine.

Il retrieveDeclaredJetParametersInOrder ovviamente aggiunge tempo extra all'esecuzione, poiché implica una chiamata extra al DB, dove recupera il testo SQL e quindi analizza i nomi ei tipi dei parametri.