Stringhe NULL

giovedì 20 settembre 2007 - 16.26

Teech Profilo | Expert

Ho un problema semplice ma non ne trovo la soluzione:

Ho una classe che gestisce una tabella in un DB SQL2005. Ho creato il metodo INSERT attraverso una T-SQL con parametri. Il codice è tipo il seguente:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra
L'errore che mi viene restituito è:
La query con parametri '(@Campo1)' prevede il parametro '@Campo1', che non è stato specificato

A questo punto ho messo nel costruttore della classe l'inizializzazione delle variabili (anche se non mi piace e se ci sono vie alternative sarò ben contento di utilizzarle) come di seguito riportato:

_strCampo1 = Sting.Empty

In questo modo funziona però mi viene compilato il campo sul DB come Blank mentre io vorrei fosse NULL. Ho provato in vari modi ma senza risultato... L'unico modo che mi ha permesso di scrivere un valore NULL è stato utilizzare _strCampo1 istanziato come SqlDataTypes.SqlString ma poi non riesco a fare il cast fra SqlString e String...

Qualcuno può aiutarmi?

Grazie
--------------
Maurizio Brini
--------------
Nessuna impresa è mai stata compiuta da un uomo ragionevole

SSUPERPIPPO Profilo | Guru

Dov'è il codice???


http://blogs.dotnethell.it/alebadalin

Teech Profilo | Expert

Scusa ma mi è scappato un "Invia messaggio" intempestivo prima di finire il post... Ora l'ho completato...

--------------
Maurizio Brini
--------------
Nessuna impresa è mai stata compiuta da un uomo ragionevole

SSUPERPIPPO Profilo | Guru

> strSQL = "INSERT INTO MiaTabella (Campo1) VALUES (@Campo1)"

> 'Crea Command e parametri
> Dim cm As New SqlClient.SqlCommand(strSQL, cn)
> cm.Parameters.Add(New SqlClient.SqlParameter("@Campo1", Data.SqlDbType.VarChar)).Value = _strCampo1

> 'Esegue SQL
> Dim dr As SqlClient.SqlDataReader = cm.ExecuteNonQuery()

Prova così:

cm.Parameters.AddWithValue("@Campo1", _strCampo1)

Fammi sapere, ciao

Alessandro

http://blogs.dotnethell.it/alebadalin

Teech Profilo | Expert

Mi piace molto di più come sintassi in quanto molto più leggibile e compatta però l'errore, se non inizializzo le variabili è identico:
La query con parametri '(@Campo1)' prevede il parametro '@Campo1', che non è stato specificato

Da quello che ho capito, l'oggetto _strCampo1 è di tipo String che può essere inizializzato da un valore (_strCampo1="Pippo") oppure assumere il valore blank (_strCampo1="") altrimenti rimane non istanziato (_strCampo1=Nothing). Il mio problema è proprio che quando l'oggetto non è istanziato vorrei venisse riportato NULL nel campo sul DB attraverso l'utilizzo dei Parameters per l'oggetto Command.
Sottolineo anche il fatto che sul DB Campo1 accetta valori NULL...

Potrei usare i campi blank anzichè NULL però è diventata una questione che voglio capire... Aiutatemi, vi prego...

P.S.: Posto anche nella sezione riguardante i DB in quanto non vorrei fosse un problema relativo al DB, anche se lo escluderei a rigor di logica...
--------------
Maurizio Brini
--------------
Nessuna impresa è mai stata compiuta da un uomo ragionevole

StefanoLep Profilo | Senior Member

Ciao, io per me ho risolto così (anche se devo ammettere che una soluzione un pochino più pulita mi piacerebbe, nel frattempo però....)

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra



Solo chi fa sbaglia :-)

SSUPERPIPPO Profilo | Guru

In effetti ho fatto delle prove e la variabile deve per forza essere inizializzata, diversamente non viene accettata come parametro.
Bel problema!
Faccio un pò di ricerche e vedo se c'è una soluzione, ti faccio sapere.

Ciao

Alessandro

http://blogs.dotnethell.it/alebadalin

Teech Profilo | Expert

Sul testo "Programmare ADO.NET 2.0" scritto da David Sceppa ho trovato questa frase dove parla dei SqlTypes:
"...L'atro principale vantaggio dell'impiego dei SqlType è che essi sono progettati per gestire i valori nulli..."

Questo mi fa pensare che non siano gestibili valori NULL con oggetti String però dopo parla di un confronto col la IsDbNull dei Datareader, quindi in lettura... Altre conferme esplicite riguardo questo "limite" non ne ho trovate ma non ho trovato nemmeno come utilizzarle...

Il codice proposto qua sopra è sicuramente funzionante ma ci perdo ancora un pò di tempo (quando ce l'avrò) per cercare una soluzione alternativa...

Grazie mille per ora...
--------------
Maurizio Brini
--------------
Nessuna impresa è mai stata compiuta da un uomo ragionevole

Teech Profilo | Expert

Ho trovato questo che si avvicina molto a quanto consigliato da StefanoLep...

http://blogs.ugidotnet.org/MatteoC/archive/2005/11/09/29535.aspx

Ho risolto il problema con una riga del tipo:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

Riguarda il Framework 1.1 ma di meglio non ho trovato nulla... Grazie a tutti per le indicazioni...

Ciao.
--------------
Maurizio Brini
--------------
Nessuna impresa è mai stata compiuta da un uomo ragionevole

SSUPERPIPPO Profilo | Guru

Più semplicemente io nel costruttore di classe inizializzerei le variabili in questo modo:

_strCampo1 = DbNull.Value

In questo modo, se non viene assegnato nessun altro valore, viene salvato NULL.
Ho provato e funziona. Ti riporto l'esempio che ho usato da me:

Dim StrProva As Object = DBNull.Value

SqlCmd.CommandText = "INSERT INTO prova (Prova) values (@Prova);"
SqlCmd.Parameters.AddWithValue("@Prova", StrProva)

...E qui ho eseguito il comando.

Ciao

Alessandro


http://blogs.dotnethell.it/alebadalin

Teech Profilo | Expert

Così però devi utilizzare variabili di tipo Object e non String... Onestamente mi piace meno (de gustibus )

In ogni caso ho incontrato un ulteriore problema che fortunatamente ho già risolto. Se usate questo tipo di parametri nelle clausole WHERE si può scrivere il command nel seguente modo altrimenti potrebbe non restituire record...

cm.CommandText="SET ANSI_NULLS OFF;" + _
"SELECT * FROM Tabella WHERE Campo1 = @Parametro;" + _
"SET ANSI_NULLS ON"

Giusto per completezza d'informazione...

Ciao a tutti
--------------
Maurizio Brini
--------------
Nessuna impresa è mai stata compiuta da un uomo ragionevole
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5