Comment puis-je ajouter une entrée fournie par l'utilisateur à une déclaration SQL?

j'essaie de créer une déclaration SQL en utilisant des données fournies par l'utilisateur. J'utilise le même code dans C#:

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

var cmd = new SqlCommand(sql, myDbConnection);
cmd.ExecuteNonQuery();

et ceci en VB.NET:

Dim sql = "INSERT INTO myTable (myField1, myField2) " &
          "VALUES ('" & someVariable & "', '" & someTextBox.Text & "');"

Dim cmd As New SqlCommand(sql, myDbConnection)
cmd.ExecuteNonQuery()

Toutefois,

  • ceci échoue lorsque l'entrée de l'utilisateur contient des guillemets simples (par exemple O'Brien ),
  • Je ne semble pas pouvoir obtenir le bon format lors de l'insertion des valeurs DateTime et
  • les gens n'arrêtent pas de me le dire que je ne devrais pas faire ça à cause de "SQL injection".

Comment faire "de la bonne façon"?

40
demandé sur Heinzi 2016-02-02 23:39:31

2 réponses

utiliser le SQL paramétrisé.

exemples

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

Remplacez vos concaténations de chaînes de caractères par @... placeholders et, ensuite, ajoutez les valeurs à votre SqlCommand. Vous pouvez choisir le nom des emplacements librement, assurez-vous juste 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 de déclarations 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 interested in one value of one row.
}

un mot de mise en garde: AddWithValue est un bon point de départ et fonctionne très bien dans la plupart des cas. Cependant, que la valeur que vous passez doit correspondre exactement au type de données du champ de base de données correspondant. Sinon, vous pourriez finir dans une situation où la conversion empêche votre requête de en utilisant un index . Notez que certains types de données SQL Server, comme char / varchar (sans précéder "n") ou date, n'ont pas de type de données .NET correspondant. Dans ces cas, Add avec le type de données correct devrait être utilisé à la place .

Pourquoi devrais-je faire ça?

autres bibliothèques d'accès aux bases de données

45
répondu Heinzi 2018-03-27 07:33:39

VB.NET exemple de Code

Ceci est le code exemple pour le wiki answer dans , en supposant Option Strict 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

mise à 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 interested in one value of one row.
End Using
1
répondu Igor 2018-03-27 07:36:25