Question

Cette question a déjà une réponse ici :

J'ai une base de données contenant des noms tels que John Doe, etc.Malheureusement, certains de ces noms contiennent des citations comme Keiran O'Keefe.Maintenant, quand j'essaie de rechercher les noms suivants :

SELECT * FROM PEOPLE WHERE SURNAME='O'Keefe' 

J'obtiens (naturellement) une erreur.

Comment puis-je empêcher cette erreur de se produire.J'utilise Oracle et PLSQL.

Était-ce utile?

La solution

Le caractère d'échappement est ', vous devrez donc remplacer le guillemet par deux guillemets.

Par exemple,

SELECT * FROM PEOPLE WHERE SURNAME='O'Keefe'

devient

SELECT * FROM PEOPLE WHERE SURNAME='O''Keefe'

Cela dit, il est probablement incorrect de le faire vous-même.Votre langage peut avoir une fonction pour échapper aux chaînes à utiliser dans SQL, mais une option encore meilleure consiste à utiliser des paramètres.Habituellement, cela fonctionne comme suit.

Votre commande SQL serait :

SELECT * FROM PEOPLE WHERE SURNAME=?

Ensuite, lorsque vous l'exécutez, vous passez "O'Keefe" en paramètre.

Étant donné que le SQL est analysé avant que la valeur du paramètre ne soit définie, la valeur du paramètre n'a aucun moyen de modifier la structure du SQL (et c'est même un peu plus rapide si vous souhaitez exécuter la même instruction plusieurs fois avec des paramètres différents).

Je dois également souligner que, même si votre exemple provoque simplement une erreur, vous vous exposez à de nombreux autres problèmes en n'échappant pas correctement les chaînes.Voir http://en.wikipedia.org/wiki/SQL_injection pour un bon point de départ ou le classique suivant bande dessinée xkcd.

alt text

Autres conseils

La solution Oracle 10 est

SELECT * FROM PEOPLE WHERE SURNAME=q'{O'Keefe}'

Les requêtes paramétrées sont vos amies, comme suggéré par Matt.

Command = SELECT * FROM PEOPLE WHERE SURNAME=?

Ils vous protégeront des maux de tête liés à

  • Chaînes avec guillemets
  • Interrogation à l'aide de dates
  • Injection SQL

L'utilisation de SQL paramétré présente d'autres avantages : elle réduit la surcharge du processeur (ainsi que d'autres ressources) dans Oracle en réduisant la quantité de travail requise par Oracle pour analyser l'instruction.Si vous n'utilisez pas de paramètres (nous les appelons variables de liaison dans Oracle), alors "select * from foo Where bar='cat'" et "select * from foo Where bar='dog'" sont traités comme des instructions distinctes, où " select * from foo où bar=:b1" est la même instruction, ce qui signifie que des éléments comme la syntaxe, la validité des objets référencés, etc... n'ont pas besoin d'être vérifiés à nouveau.Des problèmes occasionnels surviennent lors de l'utilisation de variables de liaison, qui se manifestent généralement par le fait de ne pas obtenir le plan d'exécution SQL le plus efficace, mais il existe des solutions de contournement pour cela et ces problèmes dépendent vraiment des prédicats que vous utilisez, de l'indexation et de l'asymétrie des données.

Le filtrage des entrées est généralement effectué au niveau de la langue plutôt qu'au niveau des couches de base de données.
php et .NET ont tous deux leurs bibliothèques respectives pour échapper aux instructions SQL.Vérifiez votre langue, voyez ce qui est disponible.
Si vos données sont fiables, vous pouvez simplement effectuer un remplacement de chaîne pour en ajouter un autre ' devant le ' pour y échapper.Cela suffit généralement s’il n’y a aucun risque que l’entrée soit malveillante.

Je suppose qu'une bonne question est de savoir quelle langue utilisez-vous ?
En PHP, vous feriez :SELECT * FROM PEOPLE WHERE SURNAME='mysql_escape_string(O'Keefe)'
Mais comme vous n'avez pas spécifié la langue, je vous suggère de rechercher une fonction de chaîne d'échappement mysql ou autre dans votre langue.

Pour gérer les devis si vous utilisez Zend Framework, voici le code

$db = Zend_Db_Table_Abstract::getDefaultAdapter();

$db->quoteInto('your_query_here = ?','your_value_here');

Par exemple ;

//SELECT * FROM PEOPLE WHERE SURNAME='O'Keefe' will become
SELECT * FROM PEOPLE WHERE SURNAME='\'O\'Keefe\''

Trouvé dans les moins de 30 ans sur Google...

FAQ sur Oracle SQL

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top