Comment les parameters SQL fonctionnent-ils en interne?

Un collègue et moi étions en train de naviguer sur SO lorsque nous sums tombés sur une question à propos de SQL Injection, et cela nous a fait nous requestr: comment les requêtes paramétrées fonctionnent-elles en interne? L'API que vous utilisez (en supposant qu'elle supporte les requêtes paramétrées) effectue une concaténation, en combinant la requête avec les parameters? Ou est-ce que les parameters le rendent au moteur SQL séparément de la requête, et aucune concaténation n'est effectuée du tout?

Google n'a pas été très utile, mais peut-être que nous n'avons pas cherché la bonne chose.

Les parameters le rendent au moteur SQL séparément de la requête. Plan d'exécution calculé ou réutilisé pour la requête paramétrée, puis la requête est exécutée par le moteur sql avec les parameters.

Les parameters rendent le server SQL intact et "emballés" individuellement avec des méta-données indiquant leur type, qu'il s'agisse d'input ou de sortie etc. Comme le souligne Alex Reitbort, c'est parce que les instructions paramétrées sont un concept au niveau du server. manière d'invoquer des commands provenant de différentes couches de connection.

Je doute que SQL SERVER génère une string de requête complète à partir de la requête paramétrée donnée dans laquelle la list de parameters est concaténée.

Il parsing très probablement la string de command paramétrée donnée en la divisant en une structure de données interne basée sur des mots et des symboles réservés (SELECT, FROM, ",", "+", etc.). Dans cette structure de données, il existe des propriétés / locations pour des valeurs telles que les noms de tables, les littéraux, etc. C'est ici qu'il copy (verbatim) chaque paramètre transmis (de la list) dans la section appropriée de cette structure.

donc votre @UserName valeur de: 'x'; supprimer des users –

dans ne doit jamais être échappé, juste utilisé comme la valeur littérale c'est vraiment.

Les parameters sont transmis avec la requête (pas dans la requête) et sont automatiquement échappés par l'API lorsqu'ils sont envoyés conformément au protocole de communication de database sous-jacent.

Par exemple, vous pourriez avoir

Query: <<<<select * from users where username = :username>>>> Param: <<<<:username text<<<<' or '1' = '1>>>>>>>> 

Ce n'est pas l'enencoding exact que tout protocole de database utilise réellement, mais vous avez l'idée.