IF NOT EXISTS

Manserk
Invité n'ayant pas de compte PHPfrance

22 nov. 2010, 10:49

j'ai une requête :

Code : Tout sélectionner

INSERT INTO tb_url (lbl_url) VALUES (?)
elle fonctionne bien :D

maintenant j'aimerais qu'elle gère de ne pas enregistrer 2 fois la même url, donc :

Code : Tout sélectionner

INSERT IF NOT EXIST INTO tb_url (lbl_url) VALUES (?)
elle, ne marche pas :( , j'ai aussi essayé avec un s a la fin de EXIST

j'utilise pdo, en php, y a t'il une subtilité ?

Manserk
Invité n'ayant pas de compte PHPfrance

22 nov. 2010, 11:27

j'ai aussi essayé ceci :
INSERT INTO tb_url (lbl_url) VALUES (:lien) IF NOT EXISTS(SELECT lbl_url FROM tb_url WHERE tb_url= :lien)

Modérateur PHPfrance
Modérateur PHPfrance | 6373 Messages

22 nov. 2010, 12:36

"elle ne marche pas": erreur ? enregistre quand même ?

MAnserk
Invité n'ayant pas de compte PHPfrance

22 nov. 2010, 12:51

pas d'enregistrements si les liens sont déjà dans la base ou non

j'ai l'erreur suivante :

Code : Tout sélectionner

exception 'PDOException' with message 'SQLSTATE[42000]: Syntax error or access violation: 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 'IF NOT EXISTS INTO tb_url (lbl_url) VALUES ('http://www.manserk.com/')' at line 1
donc ma syntaxe n'est pas la bonne, mais je ne sais pas quelle est la bonne

Modérateur PHPfrance
Modérateur PHPfrance | 6373 Messages

22 nov. 2010, 13:03

Quelle est la version de MySQL?

Eléphanteau du PHP | 11 Messages

22 nov. 2010, 13:42

je suis en version 5.1.36

Code : Tout sélectionner

Version du serveur: 5.1.36-community-log

j'ai cherché un peu et comme solution je pense que je pourrais faire une requête select séparé avant, mais la table serra assez grosse donc je cherche a mettre ça en une seule requête

Modérateur PHPfrance
Modérateur PHPfrance | 6373 Messages

22 nov. 2010, 14:49

J'ai regardé vite fait la doc et je ne suis pas sûr que ta syntaxe existe, au moins dans cette version, par contre il y a le mot clé IGNORE, peut être peux-tu regarder de ce côté : http://dev.mysql.com/doc/refman/5.1/en/insert.html

devlop78
Invité n'ayant pas de compte PHPfrance

22 nov. 2010, 15:18

Ton cas est plus une contrainte d'intégrité, et il serait intéressant que tu utilises la contrainte "UNIQUE" fournie par MySQL. N'oublie pas l'interclassement approprié pour ignorer la casse.

a+

devlop78
Invité n'ayant pas de compte PHPfrance

22 nov. 2010, 15:21

J'ai regardé vite fait la doc et je ne suis pas sûr que ta syntaxe existe, au moins dans cette version, par contre il y a le mot clé IGNORE, peut être peux-tu regarder de ce côté : http://dev.mysql.com/doc/refman/5.1/en/insert.html
Le mot clé "ignore" ne fera rien dans ce cas. Il va juste déterminé si lorsque ton insertion échoue, Mysql émettra une erreur ou pas. Si tu mets ignore et que ton insertion échoue, tu ne le sauras qu'en regardant le nombre de lignes altérées.

Modérateur PHPfrance
Modérateur PHPfrance | 6373 Messages

22 nov. 2010, 15:29

En fait je pensais que la contrainte était déjà présente et que c'était pour gérer le cas proprement, mais oui en effet la contrainte d'unicité serait le premier pas bien vu :)

Eléphanteau du PHP | 11 Messages

24 nov. 2010, 11:30

Bonjours, j'avance, un peu
d'abord j'ai décidé de laisser tomber le php pour faire des test directement dans mysql ça va beaucoup plus vite ! :D
ensuite j'ai cherché sur google les attributs UNIQUE et IGNORE mais je n'ais rien trouvé d'interressant :|
INSERT INTO tb_url
(lbl_url)
SELECT lbl_url
FROM tb_url
WHERE not exists (select lbl_url from tb_url Where lbl_url = 'http://www.manserk.com/')
avec cette requete je n'eregistre pas l'url si elle est deja dans la table, c'est ce que je veux
mais si elle est deja dans la table elle est tout simplement doublée :shock: ce que je ne veux pas

comment faire en sorte que le 'SELECT ... 'http://www.manserk.com/' soit juste un test et pas l'enregistrement a faire ?

Modérateur PHPfrance
Modérateur PHPfrance | 6373 Messages

24 nov. 2010, 11:43

Ce dont parlait devlop78 c'est une contrainte sur la colonne, non pas dans la requête. Tu dis à la création de la table (ou après en la modifiant) que telle colonne ne peut contenir deux fois la même valeur :

http://dev.mysql.com/doc/refman/5.0/fr/ ... table.html
:arrow:
| [CONSTRAINT [symbol]] UNIQUE [INDEX]

devlop78
Invité n'ayant pas de compte PHPfrance

24 nov. 2010, 21:39

Vérifie bien ton interclassement, il serait assez bête d'accepter une valeur avec juste une différence de majuscule/minuscule.

Ensuite, on peut très bien imaginer

INSERT INTO tb_url
(TRIM(lbl_url)) ...

Pour éviter d'avoir des espaces avant et après, et ainsi des doublons sur des différences d'espace.

Ensuite, on peut aller plus loin avec Mysql ou PHP, pour n'enregistrer que l'hôte, afin d'éviter d'avoir des différences sur des pages.

Voilà :)

Eléphanteau du PHP | 11 Messages

25 nov. 2010, 11:28

Pour ce qui est des valeurs ce n'est pas un problème puisque ce n'est pas un utilisateur qui rentre les urls donc le même format est toujours respecté

bon et bien ça a l'air de fonctionner : voici ma requête
 INSERT IGNORE INTO tb_url (lbl_url) VALUES (:link)
+ j'ai mis le champ en unique

merci a tous

devlop78
Invité n'ayant pas de compte PHPfrance

25 nov. 2010, 20:59

Attention que dans ton cas, Mysql ne renverra pas d'erreur, donc pas moyen de se fier à un

if (mysql_query (...)),

puisqu'il te renverra true.