2008-12-17 4 views
7

Je n'arrive pas à trouver la syntaxe appropriée pour autoriser la transmission d'une chaîne ou d'une valeur NULL à la base de données. Voici mon code:Problème lors de l'insertion de la chaîne ou de la valeur NULL dans la base de données SQL Server

string insertString = String.Format(
    @"INSERT INTO upload_history (field1, field2, field3) 
    VALUES ('{0}', '{1}', '{2}')", 
    varField1, varField2, varField3); 

je guillemets simples autour des espaces réservés variables de telle sorte que la base de données serait bien accepter une valeur de chaîne. Cependant, si NULL est passé, il finit par entrer dans la base de données en tant que chaîne "NULL".

Y a-t-il un moyen de laisser les guillemets simples hors de la chaîne InsertCommand et d'ajouter des guillemets simples à mes variables?

Répondre

22

Ne pas concaténer la chaîne (string.Format) - paramètres d'utilisation (@p1 etc) - vous pouvez passer DBNull.Value signifie null à SQL Server

SqlCommand cmd = new SqlCommand(); 
cmd.CommandText = @"INSERT INTO upload_history (field1, field2, field3) 
    VALUES (@p1, @p2, @p3)"; 
cmd.Parameters.AddWithValue("@p1", (object)someVar ?? DBNull.Value); 
//... 

Cela vous protège également de l'injection SQL

+0

Je reçois l'erreur suivante lors de l'utilisation « someVar ?? DBNull.Value » comme ci-dessus: « Opérateur" ?? ne peut pas être appliqué aux opérandes pour la chaîne de caractères et System.DBNull "Des pensées sur comment cela fonctionnerait avec une chaîne? – buzzzzjay

+2

@buzzzzjay ajoute un '(objet)' devant l'un d'entre eux. –

+0

Doux! Cela aide vraiment! Merci! – buzzzzjay

5

La concaténation de la chaîne avec String.Format peut être un gros risque pour la sécurité (Injection SQL), et également problématique si vous voulez insérer le caractère.

Solution:

cmd.CommandText = "INSERT INTO upload_history (field1, field2, field3) " + 
    "VALUES (@p1, @p2, @p3)"; 
cmd.Parameters.AddWithValue("@p1", varField1); 
cmd.Parameters.AddWithValue("@p2", varField2); 
cmd.Parameters.AddWithValue("@p3", varField3); 
cmd.ExecuteNonQuery(); 
+0

C'est aussi une bonne réponse mais Marc vous a battu dessus. Merci pour la suggestion. – beardog

2

Dans l'esprit de répondre à la question comme il a été demandé, et d'être pleinement conscient que la refactorisation du code pour paramaterizing les requêtes est la bonne solution, vous pouvez écrire une fonction qui retourne soit une chaîne entre guillemets simples ou une valeur de chaîne NULL non quotée, puis supprimez les guillemets simples de la chaîne de requête.

string insertString = String.Format( @"INSERT INTO upload_history (field1, field2, field3)  VALUES ({0}, {1}, {2})", ToStringorNull(varField1), ToStringorNull(varField2), ToStringorNull(varField3)); 

Si vous utilisez VS 2008, vous pouvez même l'implémenter en tant que méthode d'extension.

string insertString = String.Format( @"INSERT INTO upload_history (field1, field2, field3)  VALUES ({0}, {1}, {2})", varField1.ToStringorNull, varField2.ToStringorNull, varField3.ToStringorNull); 

Je vais laisser créer la fonction ToStringorNull pour vous - il est pas difficile :-)

Questions connexes