Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 20/07/2009, à 07:10

Solaris974

[RESOLU] Requête SQL petit problème... WHERE NOT EXISTS

Bonjour, voici mon petit problème :

#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHERE NOT EXISTS (SELECT * FROM mail.alias WHERE address='postmaster@un.truc' at line 1

INSERT INTO mail.alias (address, goto, domain, created, modified, active) 
VALUES ( 'postmaster@un.truc.re' , 'postmaster@truc.re' , 'un.truc.re' , NOW() , NOW() , '1' )
WHERE NOT EXISTS (
SELECT * FROM mail.alias WHERE goto='postmaster@truc.re')

J'essaie d'insérer une ligne dans une table mais en vérifiant si la ligne n'existe pas déjà..
Je n'y arrive pas, voyez vous une erreur quelque part ?

Je ne fais que très rarement du SQL, merci

Dernière modification par Solaris974 (Le 31/08/2009, à 08:17)


« La Terre est le berceau de l'humanité... Mais passe-t-on sa vie entière dans un berceau ? »

Quad-core i5 3,4Ghz  / 16Go DDR3  /  nVidia GTX 660 2Go OC  /  SSD OCZ Agility 4 256Go

Hors ligne

#2 Le 20/07/2009, à 12:18

alexduf

Re : [RESOLU] Requête SQL petit problème... WHERE NOT EXISTS

Bonjour,

il me semble que le "EXISTS" implique un nommage des tables, surtout quand la selection se fait sur la même table :

INSERT INTO mail.alias i (address, goto, domain, created, modified, active) 
VALUES ( 'postmaster@un.truc.re' , 'postmaster@truc.re' , 'un.truc.re' , NOW() , NOW() , '1' )
WHERE NOT EXISTS (
SELECT * FROM mail.alias s WHERE s.goto=i.goto)

Même si je ne suis pas convaincu qu'on puisse utiliser le "exists" dans une requête d'insert. (Je me trompe peut-être hein !)

Hors ligne

#3 Le 20/07/2009, à 12:26

Totor

Re : [RESOLU] Requête SQL petit problème... WHERE NOT EXISTS

Bonjour,

Je ne connais pas MySQL, mais la synthaxe annoncée me parait quelque peu étrange.
Je pense que l'utilisation d'un EXISTS nécessite l'utilisation d'un requête SELECT.

synopsis


-- Lucid Lynx --

Hors ligne

#4 Le 20/07/2009, à 15:50

Khyl

Re : [RESOLU] Requête SQL petit problème... WHERE NOT EXISTS

Totor a raison, il faut un select, la bonne syntaxe c'est plutôt

INSERT INTO mail.alias (address, goto, domain, created, modified, active) 
SELECT 'postmaster@un.truc.re' , 'postmaster@truc.re' , 'un.truc.re' , NOW() , NOW() , '1'
WHERE NOT EXISTS (SELECT * FROM mail.alias WHERE address='postmaster@un.truc.re' and goto='postmaster@truc.re' and domain='un.truc.re')

Dernière modification par Khyl (Le 20/07/2009, à 15:52)

Hors ligne

#5 Le 20/07/2009, à 16:26

pipou24

Re : [RESOLU] Requête SQL petit problème... WHERE NOT EXISTS

Je viens de retrouver un vieux cours http://deptinfo.unice.fr/~grin/messupports/sql.pdf . C'est ca.
Par contre inutile de reprendre les éléments dans le second select :

INSERT INTO mail.alias (address, goto, domain, created, modified, active) 
SELECT 'postmaster@un.truc.re' , 'postmaster@truc.re' , 'un.truc.re' , NOW() , NOW() , '1'
WHERE NOT EXISTS (SELECT * FROM mail.alias)

Dernière modification par pipou24 (Le 20/07/2009, à 16:31)


Non geek et fier de l'être. ㋡

Hors ligne

#6 Le 20/07/2009, à 18:00

Totor

Re : [RESOLU] Requête SQL petit problème... WHERE NOT EXISTS

INSERT INTO mail.alias (address, goto, domain, created, modified, active)
SELECT 'postmaster@un.truc.re' , 'postmaster@truc.re' , 'un.truc.re' , NOW() , NOW() , '1'
WHERE NOT EXISTS (SELECT * FROM mail.alias)

A moins qu'elle soit vide, cette requête n'insérera jamais d'enregistrement dans la table.
SELECT * FROM mail.alias retournant toujours des enregistrements, la clause where ne sera jamais vérifiée (donc pas d'insertion)

Il faut donc ajouter une clause WHERE au SELECT * FROM mail.alias qui filtre sur les valeurs de champs que l'on souhaite insérer (En toute logique, il s'agit de la clé primaire).

Une autre solution consiste à ne pas effectuer de INSERT INTO... SELECT  mais plutôt un INSERT INTO ... ON DUPLICATE KEY UPDATE...


-- Lucid Lynx --

Hors ligne

#7 Le 20/07/2009, à 18:22

pipou24

Re : [RESOLU] Requête SQL petit problème... WHERE NOT EXISTS

hmm exact. J'ai écrit ça en pensant à mon WHERE ... NOT IN mais même en l'état, c'est faux.


Non geek et fier de l'être. ㋡

Hors ligne

#8 Le 20/07/2009, à 18:32

obiwankennedy

Re : [RESOLU] Requête SQL petit problème... WHERE NOT EXISTS

il ya pas moyen de definir le champ goto comme unique ? et de fait si tu essaies d'inserer et que ca existe deja sql te retournera une erreur?


Dans mes logiciels, j'écris ton nom.
SGNGD: SvgGd is Not GD
Rolisteam

Hors ligne

#9 Le 20/07/2009, à 20:14

alexduf

Re : [RESOLU] Requête SQL petit problème... WHERE NOT EXISTS

obiwankennedy a écrit :

il ya pas moyen de definir le champ goto comme unique ? et de fait si tu essaies d'inserer et que ca existe deja sql te retournera une erreur?

Le soucis dans ce genre de "manip" c'est qu'en cas de réel problème, il risque de passer inaperçu. (style base de données inaccessible ou autre).
D'une manière générale on essaye de ne pas utiliser les erreurs (techniques) pour des traitements fonctionnels.

Si l'application n'est pas vouée à subir de fortes charges, peut-être que faire un select au préalable est préférable non ?

Hors ligne

#10 Le 20/07/2009, à 20:53

obiwankennedy

Re : [RESOLU] Requête SQL petit problème... WHERE NOT EXISTS

Oui mais de fait, si tu laisses la possibilité d'avoir un  enregistrement en double dans ta base alors que ton SI ne l'autorise pas. La conception de ta base est bancale. Donc définir le champ unique règle le problème en soit. Ensuite, sql retournera une erreur de type "enregistrement impossible clé déjà présente" mais c'est vrai que ca n'est pas propre mais gérer a la "mano" l'insertion, c'est pas non plus propre. Donc le mieux, c'est effectivement de tester au préalable et de définir le champ en unique.


Dans mes logiciels, j'écris ton nom.
SGNGD: SvgGd is Not GD
Rolisteam

Hors ligne

#11 Le 20/07/2009, à 22:44

Totor

Re : [RESOLU] Requête SQL petit problème... WHERE NOT EXISTS

obiwankennedy a écrit :

il ya pas moyen de definir le champ goto comme unique ? et de fait si tu essaies d'inserer et que ca existe deja sql te retournera une erreur?

Que ce soit le champ "goto" ou tout autre champ, la problématique du test d'insertion de doublon est toujours présente.
- Effectuer ou ne pas le test d'existence avant l'insertion ?
- S'appuyer ou pas sur les vérifications relationnelles du SGBD ?

Tout dépend de ce que l'utilisateur lambda attend du programme :
- Si il se fou de savoir que l'enregistrement existe déjà et s'il n'y a pas de traitement spécifique en cas d'existence, pourquoi ne pas réaliser l' insertion en utilisant l'ordre INSERT sous la forme INSERT INTO ... ON DUPLICATE KEY UPDATE goto=goto; (pour ne rien changer aux données existantes)
- Si il faut lui indiquer que l'enregistrement est déjà présent en base ou effectuer un traitement spécifique (ex traçage du rejet), je suis d'avis à tester l'existence de l'enregistrement avant d'effectuer l'INSERT et ce quelque soit la volumétrie de la table. En effet, la volumétrie est un faux problème dès lors que des indexes sont positionnés sur les bons champs de sélection. J'ai déjà réalisé des requêtes  sur des tables ayant plus de 200 millions d'enregistrements et avoir le résultat en 1/10 sec ! Bon, OK c'était sous Oracle.

Pour moi, les mécanismes d'erreurs "techniques" du SGBD (ex. Vérification de l'unicité de l'enregistrement par rapport à la clé primaire de la table) ne sont là que pour palier aux erreurs de développement et peuvent entrainer d'autres erreurs (ex. si elles ne sont pas correctement interprétées ou traitées)


-- Lucid Lynx --

Hors ligne

#12 Le 30/08/2009, à 19:04

Solaris974

Re : [RESOLU] Requête SQL petit problème... WHERE NOT EXISTS

Re slt les gars wink
Désolé de vous avoir lâché, j'étais sur autre chose ces derniers temps, mais le je reviens la dessus.

Donc la requête ici est bonne

Totor a écrit :

INSERT INTO mail.alias (address, goto, domain, created, modified, active)
SELECT 'postmaster@un.truc.re' , 'postmaster@truc.re' , 'un.truc.re' , NOW() , NOW() , '1'
WHERE NOT EXISTS (SELECT * FROM mail.alias)

si ce n'est qu'il manqué juste

INSERT INTO mail.alias (address, goto, domain, created, modified, active) 
SELECT 'postmaster@un.truc.re' , 'postmaster@truc.re' , 'un.truc.re' , NOW() , NOW() , '1'
FROM mail.alias
WHERE NOT EXISTS (SELECT * FROM mail.alias)

Maintenant le truc c'est que j'ai un peu modifier la chose pour qu'elle soie comme ca :

INSERT INTO mail.alias (address, goto, domain, created, modified, active) 
SELECT 'postmaster@un.truc.re' , 'postmaster@truc.re' , 'un.truc.re' , NOW() , NOW() , '1'
FROM mail.alias
WHERE NOT EXISTS (SELECT * FROM mail.alias WHERE address='postmaster@un.truc.re' AND goto='postmaster@truc.re')

et j'ai environ 250 requête du genre, et au lieu de me retrouver avec 250 enregistrement....
je me retrouve avec 30 000 000......:lol:
j'ai des enregistrements qui se font plusieurs fois en effet..

Ai-je fais une gaffe ??

Merci!


« La Terre est le berceau de l'humanité... Mais passe-t-on sa vie entière dans un berceau ? »

Quad-core i5 3,4Ghz  / 16Go DDR3  /  nVidia GTX 660 2Go OC  /  SSD OCZ Agility 4 256Go

Hors ligne

#13 Le 31/08/2009, à 08:16

Solaris974

Re : [RESOLU] Requête SQL petit problème... WHERE NOT EXISTS

Voilà la solus FINALE !!

INSERT INTO mail.alias (address, goto, domain, created, modified, active) 
SELECT 'postmaster@un.truc.re' , 'postmaster@truc.re' , 'un.truc.re' , NOW() , NOW() , '1'
FROM mail.alias
WHERE NOT EXISTS (SELECT * FROM mail.alias WHERE address='postmaster@un.truc.re' AND goto='postmaster@truc.re')
LIMIT 1

et tout marche pour le mieux! cool


Merci à vous wink

Dernière modification par Solaris974 (Le 31/08/2009, à 08:16)


« La Terre est le berceau de l'humanité... Mais passe-t-on sa vie entière dans un berceau ? »

Quad-core i5 3,4Ghz  / 16Go DDR3  /  nVidia GTX 660 2Go OC  /  SSD OCZ Agility 4 256Go

Hors ligne

#14 Le 31/08/2009, à 10:58

HP

Re : [RESOLU] Requête SQL petit problème... WHERE NOT EXISTS

Solaris974 a écrit :

Voilà la solus FINALE !!

INSERT INTO mail.alias (address, goto, domain, created, modified, active) 
SELECT 'postmaster@un.truc.re' , 'postmaster@truc.re' , 'un.truc.re' , NOW() , NOW() , '1'
FROM mail.alias
WHERE NOT EXISTS (SELECT * FROM mail.alias WHERE address='postmaster@un.truc.re' AND goto='postmaster@truc.re')
LIMIT 1

et tout marche pour le mieux! cool

Ouais, t'as réinventé le ALTER TABLE accompagné de la contrainte DEFAULT, là… bravo !
Même si c'est plus simple d'utiliser ALTER TABLE comme il faut smile


cat /dev/urandom >/dev/null 2>&1 #github

Hors ligne

#15 Le 31/08/2009, à 19:39

Solaris974

Re : [RESOLU] Requête SQL petit problème... WHERE NOT EXISTS

Bah disons que chui un peu une brelle en SQL donc voilà quoi mdr!

je verrais ca alors lol


« La Terre est le berceau de l'humanité... Mais passe-t-on sa vie entière dans un berceau ? »

Quad-core i5 3,4Ghz  / 16Go DDR3  /  nVidia GTX 660 2Go OC  /  SSD OCZ Agility 4 256Go

Hors ligne

#16 Le 01/09/2009, à 17:18

Solaris974

Re : [RESOLU] Requête SQL petit problème... WHERE NOT EXISTS

Re bonsoir,
j'ai encore une petite question pour l'exemple suivant :

INSERT INTO mail.mailbox (username, password, name, maildir, quota, created, modified, active, domain) 
SELECT 'stephp@truc.re', '$1$Cun7Zjhgjgjgjudh47TeaCfz1', 'Steph PRI', 'stephp@truc.re/', '0', 'now()', 'now()', '1', 'truc.re'
FROM mail.mailbox WHERE NOT EXISTS (
SELECT * 
FROM mail.mailbox 
WHERE username='stephp@truc.re' 
AND name='Steph PRI') 
LIMIT 1;

Y a-t-il une option pour ne pas respecter la casse au niveau du « AND name='Steph PRI' »  ??

merci encore roll
Je cherche toujours sur GG


« La Terre est le berceau de l'humanité... Mais passe-t-on sa vie entière dans un berceau ? »

Quad-core i5 3,4Ghz  / 16Go DDR3  /  nVidia GTX 660 2Go OC  /  SSD OCZ Agility 4 256Go

Hors ligne

#17 Le 01/09/2009, à 17:23

Solaris974

Re : [RESOLU] Requête SQL petit problème... WHERE NOT EXISTS

Dsl de vous avoir dérangé, j'ai trouvé un moyen avec upper()

INSERT INTO mail.mailbox (username, password, name, maildir, quota, created, modified, active, domain) 
SELECT 'stephp@truc.re', '$1$Cun7Zjhgjgjgjudh47TeaCfz1', 'Steph PRI', 'stephp@truc.re/', '0', 'now()', 'now()', '1', 'truc.re'
FROM mail.mailbox WHERE NOT EXISTS (
SELECT * 
FROM mail.mailbox 
WHERE username='stephp@truc.re' 
AND upper(name)='Steph PRI') 
LIMIT 1;

« La Terre est le berceau de l'humanité... Mais passe-t-on sa vie entière dans un berceau ? »

Quad-core i5 3,4Ghz  / 16Go DDR3  /  nVidia GTX 660 2Go OC  /  SSD OCZ Agility 4 256Go

Hors ligne

#18 Le 01/09/2009, à 20:16

alexduf

Re : [RESOLU] Requête SQL petit problème... WHERE NOT EXISTS

par contre, attention, il me semble que l'utilisation de la fonction upper anéantit l'utilisation des indexes (si tu as mis un index sur cette colonne)
Donc l'accès est beaucoup moins rapide, puisque le traitement parcours l'ensemble de la table.

Pour contourner ça, tu peux ajouter une colonne à ta table, avec ton champ en majuscules, puis tu effectue la comparaison sur celui-ci.

Enfin, ce n'est utile que si tu as un gros volume de données.

Hors ligne