pourquoi utiliseriez-vous L'instruction WHERE 1=0 en SQL?
j'ai vu une requête exécutée dans un fichier journal sur une application. et il contenait une requête comme:
SELECT ID FROM CUST_ATTR49 WHERE 1=0
à quoi sert une telle requête qui ne doit rien rapporter?
8 réponses
une requête comme celle-ci peut être utilisée pour ping la base de données. La clause:
WHERE 1=0
garantit que les données non sont renvoyées, donc pas de frais CPU, pas de trafic réseau ou autre consommation de ressources.
une requête comme celle-ci peut tester pour:
- disponibilité du serveur
- CUST_ATTR49 table existence
- ID existence de colonne
- maintenir une connexion vivante
- déclencher un feu sans changer de ligne
- gérer plusieurs ou conditions dans les requêtes dynamiques(E. g
WHERE 1=0 OR <condition>
)
une usecase à laquelle je peux penser: vous avez un formulaire de filtre où vous ne voulez pas avoir de résultats de recherche. Si vous spécifiez un filtre, il est ajouté à la clause where.
Ou il est généralement utilisé si vous devez créer une requête sql à la main. Par exemple: vous ne voulez pas vérifier si la clause où est vide ou non..et vous pouvez juste ajouter des trucs comme ça:
where := "WHERE 0=1"
if X then where := where + " OR ... "
if Y then where := where + " OR ... "
(si vous connectez les clauses avec ou vous avez besoin de 0=1, si vous avez et vous avez 1=1)
peut également être utilisé pour extraire le schéma d'une table sans extraire de données à l'intérieur de cette table. Comme L'a dit Andrea Colleoni, ce seront les autres avantages de l'utilisation de ce système.
d'après Greg
si la liste des conditions n'est pas connue au moment de la compilation et est construit au moment de l'exécution, vous n'avez pas à vous inquiéter si vous en avez un ou plus d'une condition. Vous pouvez les générer tous comme:
et
et les concaténer tous ensemble. Avec le 1=1 au départ, le initiale et a quelque chose à associer avec.
j'ai jamais vu cela utilisé pour tout type de protection contre l'injection, comme vous dire qu'il ne semble pas que ce serait d'une grande aide. Je l'ai vu utilisé comme un la mise en œuvre de commodité. Le moteur de requête SQL finira par ignorer le 1=1 ne devrait donc pas avoir d'impact sur le rendement.
pourquoi quelqu'un utiliserait où 1=1 et
certains systèmes utilisent des scripts et peuvent définir dynamiquement des enregistrements sélectionnés pour être cachés d'une liste complète; ainsi une condition fausse doit être passée au SQL. Par exemple, trois dossiers sur 500 peuvent porter la mention "vie privée" pour des raisons médicales et ne devraient pas être visibles par tout le monde. Une interrogation dynamique permettra de contrôler les 500 documents qui sont visibles pour les RH, tandis que 497 sont visibles pour les gestionnaires. Une valeur serait passée à la clause SQL qui est conditionnellement définie, i.e. 'WHERE 1=1' ou ' WHERE 1=0 ', en fonction de qui est connecté au système.
si l'Utilisateur a l'intention de n'ajouter que des enregistrements, alors la méthode la plus rapide est d'ouvrir le recordset sans retourner aucun enregistrement existant.
comme réponse - mais aussi comme clarification à ce que @AndreaColleoni a déjà mentionné:
gérer un grand nombre de conditions dans les requêtes dynamiques (E. g
WHERE 1=0 OR <condition>
)
utilisation comme interrupteur marche / arrêt
j'utilise ceci comme une instruction d'interrupteur (on/off) pour des parties de ma requête.
si je devais utiliser
WHERE (0=? OR first_name = ?) AND (0=? OR last_name = ?)
alors je peux utiliser la première variable bind ( ?
) pour activer ou désactiver le critère de recherche first_name
. , et la troisième variable bind ( ?
) pour activer ou désactiver le critère last_name
.
pour seulement ces deux critères, il ne semble pas que utile, comme une chose pourrait il est juste plus facile de faire la même chose en construisant dynamiquement votre condition où en mettant seulement first_name
ou last_name
, ou les deux, ou aucun. Donc votre code devra construire dynamiquement 4 versions de la même requête. Imaginez ce qui se passerait si vous aviez 10 critères différents à considérer, alors combien de combinaisons de la même requête vous devrez gérer?
Compiler L'Optimisation Du Temps
je pourrais aussi ajouter que l'ajout du 0=? comme un commutateur de variable bind ne fonctionnera pas très bien si tous vos critères sont indexés. Le run time optimizer qui sélectionnera les indices appropriés et les plans d'exécution, pourrait tout simplement ne pas voir le coût avantage de l'utilisation de l'indice dans ces prédicats légèrement plus complexes. Par conséquent, je vous conseille d'injecter le 0 / 1 explicitement dans votre requête (chaîne le concaténant dans votre sql, ou en faisant une recherche/replace). Cela donnera au compilateur la chance d'optimiser les déclarations redondantes, et donnera au exécuteur D'exécution une requête beaucoup plus simple à regarder.
(0=1 OR cond = ?) --> (cond = ?)
(0=0 OR cond = ?) --> Always True (ignore predicate)
dans la deuxième déclaration au-dessus du compilateur sait qu'il ne doit jamais même considérer la deuxième une partie de la condition ( cond = ?
), et il va simplement supprimer le prédicat entier. Si c'était une variable bind, le compilateur n'aurait jamais pu accomplir cela.
parce que vous êtes simplement, et avec force, injectant un 0/1, il n'y a aucune chance D'injections SQL.
dans Mes SQL, comme une approche, je place généralement mes points d'injection sql comme ${literal_name}, et je cherche simplement/remplace en utilisant un regex n'importe quel ${...} occurrence au sens littéral approprié, avant même que je laisse le compilateur s'en occuper. Cela conduit essentiellement à une requête stockée comme suit:
WHERE 1=1
AND (0=${cond1_enabled} OR cond1 = ?)
AND (0=${cond2_enabled} OR cond2 = ?)
semble bon, facile à comprendre, le compilateur le gère bien, et L'Optimiseur basé sur le coût D'exécution le comprend mieux et aura une plus grande probabilité de choisir le bon index.
je fais attention à ce que j'injecte. La meilleure façon de passer des variables Est et reste des variables de liaison pour toutes les évidentes raisons.
Il semble que quelqu'un essaie de pirater votre base de données. On dirait que quelqu'un a essayé l'injection mysql. Vous pouvez lire plus à ce sujet ici: Mysql Injection