Comment puis-je append une entrée fournie par l’utilisateur à une instruction SQL?

J’essaie de créer une instruction SQL à l’aide de données fournies par l’utilisateur. J’utilise un code similaire à celui-ci en C #:

var sql = "INSERT INTO myTable (myField1, myField2) " + "VALUES ('" + someVariable + "', '" + someTextBox.Text + "');"; var cmd = new SqlCommand(sql, myDbConnection); cmd.ExecuteNonQuery(); 

et ceci dans VB.NET:

 Dim sql = "INSERT INTO myTable (myField1, myField2) " & "VALUES ('" & someVariable & "', '" & someTextBox.Text & "');" Dim cmd As New SqlCommand(sql, myDbConnection) cmd.ExecuteNonQuery() 

cependant,

  • cela échoue lorsque l’entrée utilisateur contient des guillemets simples (par exemple, O'Brien ),
  • Je ne peux pas sembler obtenir le bon format lors de l’insertion des valeurs DateTime et
  • les gens continuent à me dire que je ne devrais pas faire cela à cause de “injection SQL”.

Comment puis-je le faire “correctement”?

Utilisez le SQL paramétré.

Exemples

(Ces exemples sont en C #, voir ci-dessous pour la version VB.NET.)

Remplacez vos concaténations de chaîne par des espaces réservés @... et ajoutez ensuite les valeurs à votre SqlCommand. Vous pouvez choisir librement le nom des espaces réservés, assurez-vous simplement qu’ils commencent par le signe @ . Votre exemple ressemblerait à ceci:

 var sql = "INSERT INTO myTable (myField1, myField2) " + "VALUES (@someValue, @someOtherValue);"; using (var cmd = new SqlCommand(sql, myDbConnection)) { cmd.Parameters.AddWithValue("@someValue", someVariable); cmd.Parameters.AddWithValue("@someOtherValue", someTextBox.Text); cmd.ExecuteNonQuery(); } 

Le même modèle est utilisé pour d’autres types d’instructions SQL:

 var sql = "UPDATE myTable SET myField1 = @newValue WHERE myField2 = @someValue;"; // see above, same as INSERT 

ou

 var sql = "SELECT myField1, myField2 FROM myTable WHERE myField3 = @someValue;"; using (var cmd = new SqlCommand(sql, myDbConnection)) { cmd.Parameters.AddWithValue("@someValue", someVariable); using (var reader = cmd.ExecuteReader()) { ... } // Alternatively: object result = cmd.ExecuteScalar(); // if you are only interestd in one value of one row. } 

AddWithValue : AddWithValue est un bon sharepoint départ et fonctionne très bien dans la plupart des cas. Toutefois, la valeur que vous transmettez doit correspondre exactement au type de données du champ de firebase database correspondant. Sinon, vous risquez de vous retrouver dans une situation où la conversion empêche votre requête d’ utiliser un index . Notez que certains types de données SQL Server, tels que char / varchar (sans précéder “n”) ou date n’ont pas de type de données .NET correspondant. Dans ces cas, vous devez utiliser Add avec le type de données approprié .

Pourquoi devrais-je faire ça?

  • C’est plus sécurisé : il arrête l’ injection SQL . ( Bobby Tables ne supprimera pas vos dossiers d’étudiant. )

  • C’est plus facile: pas besoin de manipuler des guillemets simples et doubles ou de rechercher la représentation correcte des chaînes de date.

  • C’est plus stable: O'Brien ne plantera pas votre application simplement parce qu’il insiste pour garder son nom étrange.

Autres bibliothèques d’access aux bases de données

  • Si vous utilisez un OleDbCommand au lieu d’un SqlCommand (par exemple, si vous utilisez une firebase database MS Access), utilisez ? au lieu de @... comme espace réservé dans le SQL. Dans ce cas, le premier paramètre de AddWithValue est sans importance; à la place, vous devez append les parameters dans le bon ordre. La même chose est vraie pour OdbcCommand .

  • Entity Framework prend également en charge les requêtes paramétrées.

Exemple de code VB.NET

Ceci est l’exemple de code pour la réponse wiki dans vb.net , en supposant que Option Ssortingct On et Option Infer On .

INSÉRER

 Dim sql = "INSERT INTO myTable (myField1, myField2) " & "VALUES (@someValue, @someOtherValue);" Using cmd As New SqlCommand(sql, myDbConnection) cmd.Parameters.AddWithValue("@someValue", someVariable) cmd.Parameters.AddWithValue("@someOtherValue", someTextBox.Text) cmd.ExecuteNonQuery() End Using 

METTRE À JOUR

 Dim sql = "UPDATE myTable SET myField1 = @newValue WHERE myField2 = @someValue;" ' see above, same as INSERT 

SÉLECTIONNER

 Dim sql = "SELECT myField1, myField2 FROM myTable WHERE myField3 = @someValue;" Using cmd As New SqlCommand(sql, myDbConnection) cmd.Parameters.AddWithValue("@someValue", someVariable) Using reader = cmd.ExecuteReader() ' ... End Using ' Alternatively: Dim result = cmd.ExecuteScalar() ' if you are only interestd in one value of one row. End Using