[MySQL]Auto increment et doublons

Auto increment et doublons [MySQL] - SQL/NoSQL - Programmation

Marsh Posté le 23-10-2006 à 14:54:35    

Bonjour,
 
Je souhaite savoir s'il arrive qu' "auto increment" affecte à un champ indexé et unique une valeur déjà affectée à un autre enregistrement ?
Autrement dit, la valeur retourné par "auto increment" peut-elle être considérée comme fiable à 100% ?
 
Merci !!!!
 
P.S. : ça parait ridicule comme question, mais c'est parce que je développe avec un autre SGBD à qui il arrive de fournir un numéro déjà utilisé ... !!!

Reply

Marsh Posté le 23-10-2006 à 14:54:35   

Reply

Marsh Posté le 23-10-2006 à 14:59:09    

[:johneh] [:johneh] [:johneh]

Reply

Marsh Posté le 23-10-2006 à 15:13:49    

non, mysql bouche les trous, mais ne peut pas donner un numéro déjà en cours d'utilisation.
 
par contre, un max(id) ne retourne pas forcément le dernier numéro, puisqu'il bouche les trous.
 
florentg > bah ouais, ça peut arriver. sous oracle par exemple, il n'y a pas d'auto-incrément. on utilise des sequences à la place, qui ne sont liables à une table que grace à un trigger.
suffit de pas savoir écrire un trigger correctement, et on est foutu de générer des doublons avec une séquence (faut le faire, mais y'a pas de limites à la stupidité humaine, genre mettre des " dans du SQL, ou des ` autour des noms de champs... tu vois de quoi je veux parler ? :D)

Message cité 2 fois
Message édité par MagicBuzz le 23-10-2006 à 15:14:55
Reply

Marsh Posté le 23-10-2006 à 15:15:17    

MagicBuzz a écrit :

florentg > bah ouais, ça peut arriver. sous oracle par exemple, il n'y a pas d'auto-incrément. on utilise des sequences à la place, qui ne sont liables à une table que grace à un trigger.
suffit de pas savoir écrire un trigger correctement, et on est foutu de générer des doublons avec une séquence (faut le faire, mais y'a pas de limites à la stupidité humaine, genre mettre des " dans du SQL, ou des ` autour des noms de champs... tu vois de quoi je veux parler ? :D)


'tain [:johneh] C'est pour tenter de faires des clé primaires à partir de 52 champs ?

Reply

Marsh Posté le 23-10-2006 à 15:18:42    

hein ? de quoi donc ?
 
sinon, autre cas classique, c'est la ch'tite requête qui permet de connaître le dernier numéro de ligne inserré. souvent, le SGBD a bien créé deux lignes, mais on a récupéré deux fois le même numéro de ligne depuis deux process différent au lieu que chacun récupère le numéro de la ligne qu'il a créé (ça m'est arrivé avec un code de goret avec SQL Server : récupéré le dernier numéro de ligne créé dans le scope global au lieu de le chercher dans la connection) du coup après on a l'impression que le sgbd s'est croûté, mais en fait c'est surtout le code autour qui est bon à mettre à la poubelle ;)

Reply

Marsh Posté le 23-10-2006 à 15:23:06    

Nan j'veux dire, de manière générale, on fout toujours un pauvre int(32) pour être sûr que c'est unique, ça me paraît normal d'avoir ça en option de champs... Sauf pour les intégristes qui ne jurent que par des trucs naturels

Reply

Marsh Posté le 23-10-2006 à 15:26:16    

le problème de mv1, c'est que nombre de SGBD (MySQL, SQL Server, Access, PostGre, etc.) permettent de spécifier un compteur automatique pour un champ.
 
Là, ton champ c'est la clé primaire (donc avec une contrainte d'unicité dessus).
 
Mais parfois, quand le SGBD est encore plus pourri que MySQL (comme quoi, tout peut arriver) le compteur automatique se mélange les pinceaux et va retourner deux fois le même nombre. Ainsi, alors que le champ aurait dû être unique, il ne l'est plus, et ton insert te pète à la gueule sans raison.
 
Et là mv1 veut être sûr que MySQL lui fera pas ce coup-là. Genre, t'imagine, il est 17h50, t'es crevé, t'as qu'une envie, c'est de quitter le boulot. T'attends, les yeux rivés sur l'h'orloge de Windows. 17h59m58s, 17h59m59s... (vivivi !!!!) et 17h00m00s
Et là tu te tire une balle.
 
Ben ouais, y'a des SGBD qui sont capables de ce genre de miracles, et sans observer de changement d'heure d'hivers :D

Message cité 1 fois
Message édité par MagicBuzz le 23-10-2006 à 15:30:07
Reply

Marsh Posté le 23-10-2006 à 15:31:43    

MagicBuzz a écrit :

quand le SGBD est encore plus pourri que MySQL (comme quoi, tout peut arriver)


Vous voulez un nom ?

MagicBuzz a écrit :

Et là mv1 veut être sûr que MySQL lui fera pas ce coup-là


T'as tout compris !!!

Reply

Marsh Posté le 23-10-2006 à 16:33:32    

si tu veux pour le nom, balance :D

Reply

Marsh Posté le 23-10-2006 à 17:15:35    

4e Dimension, avec sa jolie commande "Numerotation automatique".
On est obligé d'effectuer une vérification avant de stocker son enregistrement, sinon, au bout d'un moment : PAF !!!!
 
Gare au Gorille !!!

Reply

Marsh Posté le 23-10-2006 à 17:15:35   

Reply

Marsh Posté le 23-10-2006 à 17:37:37    

faut dire qu'avec un nom pareil fallait s'en douter :D

Reply

Marsh Posté le 25-10-2006 à 09:38:13    

c'est pas standard, c'est illisible, et en plus des fois ça marche pas (genre chais plus qui qui faisait un :


insert into matable (id, nom, prenom) values (1, 'toto', "la praline" )


Et qui recevait un message d'erreur.

Reply

Marsh Posté le 25-10-2006 à 11:28:15    

:heink:
 
tes " sont peut-être dans le SQL là ?
 
moi je parle du SQL, pas de tes variables PHP.
y'a une légère différence.

Reply

Marsh Posté le 25-10-2006 à 13:09:15    

ben non...
 
Arf, ben si (là c'est la totale de chez totale :o)
 
Il faut écrire :

Code :
  1. $sql = 'SELECT nom_groupe FROM groupe WHERE nom_reference=\''.$data['nom_reference'].'\' AND nom_table=\''.$_SESSION['table'].'\'';


 
A la base, c'est quand même légèrement plus lisible non ?
Et surtout tu renvoies du SQL 100% correct.
Si demain tu dois changer ton SGBD pour un autre, alors ça marchera.
 
A noter aussi les petits malins qui font :
 

Code :
  1. select * from matable where truc like '%j\'étais%';


 
C'est une hérésie qui mérite le bûcher.
 
Le SQL n'est pas POSIX, donc les échappements POSIX ne s'y appliquement pas. SQL, c'est la norme ANSI qui est derrière, donc on respecte la norme ANSI, c'est à dire que les caractères d'échappement, c'est le caractère spécial qui est doublé :
 

Code :
  1. select * from matable where truc like '%j''étais%';


 
Seul Oracle et MySQL supportent les échappements POSIX, et comme par enchangement, c'est les deux SGBD qui sont les moins conforme à la norme SQL...
 
Et l'un comme l'autre supporte l'ANSI, donc il n'y a aucune raison de faire du POSIX.

Message cité 1 fois
Message édité par MagicBuzz le 25-10-2006 à 13:10:22
Reply

Marsh Posté le 25-10-2006 à 14:40:45    

Si tu ne veux pas antislasher, tu peux toujours utiliser la double quote comme séparateur de chaîne dans le PHP.
 
D'ailleurs, il me semble que cette syntaxe doit marcher :
 

Code :
  1. $sql = "SELECT nom_groupe FROM groupe WHERE nom_reference='$data['nom_reference']' AND nom_table='$_SESSION['table']'";


 
(c'est d'ailleurs plus performant que les concaténations)


Message édité par MagicBuzz le 25-10-2006 à 14:41:48
Reply

Marsh Posté le 25-10-2006 à 16:08:46    

c ballo madame chombier... fallait écouter RTL :o

Reply

Marsh Posté le 25-10-2006 à 17:09:12    

MagicBuzz a écrit :

c ballo madame chombier... fallait écouter RTL :o


Non suffit de connaitre php et savoir que l'évaluation dans les chaines se limite aux variables de type chaines de caractères :o
 
Obligé de sortir de la chaine pour faire sortir quoi que ce soit d'un tableau :)
 
Mais pour le coup c'est plus lisible avec des "

Code :
  1. "select * from ".$toto." where ". $machin


à mon goût que d'échapper tous les 2 mots  :pt1cable:

Reply

Marsh Posté le 25-10-2006 à 17:14:11    

je maintiens que c'est quand même plus lisible comme ça :

Code :
  1. $toto = $data['nom_reference'];
  2. $truc = $_SESSION['table'];
  3. $sql = "SELECT nom_groupe FROM groupe WHERE nom_reference='$toto' AND nom_table='$truc'";


:p (c'est un avis personnel ceci dit)

Message cité 1 fois
Message édité par MagicBuzz le 25-10-2006 à 17:14:47
Reply

Marsh Posté le 25-10-2006 à 17:16:44    

MagicBuzz a écrit :

je maintiens que c'est quand même plus lisible comme ça :

Code :
  1. $toto = $data['nom_reference'];
  2. $truc = $_SESSION['table'];
  3. $sql = "SELECT nom_groupe FROM groupe WHERE nom_reference='$toto' AND nom_table='$truc'";


:p (c'est un avis personnel ceci dit)


C'est tout sauf lisible que d'inclure comme ça des variables PHP dans une chaînede texte SQL sans vraiment les "sortir" de la chaîne !
 
Rien de plus lisible qu'un bon vieux  

Code :
  1. $sql = "SELECT nom_groupe FROM groupe WHERE nom_reference='".$toto."' AND nom_table='".$truc."'";


 
Là au moins, on voit tout de suite ou sont les variables, leurs nom, toussa ! C'est pas "perdu" au milieu de la chaine de caractère ! Qui plus es lorsqu'il y a de la coloration syntaxique !


---------------
Kao ..98 - Uplay (R6S) : kao98.7.62x39 - Origin (BF4, BF1) : kntkao98
Reply

Marsh Posté le 25-10-2006 à 17:25:11    


Sauf que mettre des " dans du sql c'est caca pourri [:petrus75]

Reply

Marsh Posté le 25-10-2006 à 17:25:53    


Le truc, c'est que ta requête SQL, au final, elle ressemble à ça :

Code :
  1. SELECT truc FROM troc WHERE machin="truc"


 
Mais mettre des " dans du SQL, spa bien ! Faut mettre des ' ! Comme ce que donne mon exemple :

Code :
  1. SELECT truc FROM troc WHERE machin='truc'


 
 [:kao98]
 
edit :  [:benou_grilled]


Message édité par kao98 le 25-10-2006 à 17:26:15

---------------
Kao ..98 - Uplay (R6S) : kao98.7.62x39 - Origin (BF4, BF1) : kntkao98
Reply

Marsh Posté le 25-10-2006 à 17:52:50    

Kao98 > c'est une question d'avis (pour les variables noyées au milieux du SQL)
pour moi le fait d'assimiler les variables à des variables SQL ne me dérange pas. peut-être parceque j'ai l'habitude de travailler avec des requêtes SQL paramétrée :spamafote:
 
en tout cas, je hais les concaténations, c'est trop laid (et lent) (et lourd) (et lipideux) (et laborieux) (et larmoyant) (et livide) (et lavasse) (et long) (et l...chuis à court de vocabulaire là :o)
 
 
(et me sors pas que c'est limpide, ludique, lucide, ... ;))

Message cité 1 fois
Message édité par MagicBuzz le 25-10-2006 à 17:55:25
Reply

Marsh Posté le 25-10-2006 à 17:54:48    

MagicBuzz a écrit :

Kao98 > c'est une question d'avis (pour les variables noyées au milieux du SQL)
pour moi le fait d'assimiler les variables à des variables SQL ne me dérange pas. peut-être parceque j'ai l'habitude de travailler avec des requêtes SQL paramétrée :spamafote:
 
en tout cas, je hais les concaténations, c'est trop laid (et lent) (et lourd) (et lipideux) (et laborieux) (et larmoyant) (et livide) (et lavasse) (et l...chuis à court de vocabulaire là :o)


Si t'aimes pas les trucs laid / lent / lourd / ..., faut pas faire de php !  [:tinostar]  
 
[/troll]


---------------
Kao ..98 - Uplay (R6S) : kao98.7.62x39 - Origin (BF4, BF1) : kntkao98
Reply

Marsh Posté le 25-10-2006 à 17:55:43    

kao98 a écrit :

Si t'aimes pas les trucs laid / lent / lourd / ..., faut pas faire de php !  [:tinostar]  
 
[/troll]


ben justement j'en fait pas [:powa]

Reply

Marsh Posté le 25-10-2006 à 17:58:48    

moi je fais des :
 

Code :
  1. string sql = string.format("select * from {0} where truc = '{1}' and bidule = '{2}', tblName, val1, val2);


 
:D
 
Plus exactement...
 

Code :
  1. private const string bouFam =   "select distinct pro.sfapro, fam.libfam " +
  2.            "from fam, pro " +
  3.            "where pro.codsoc = :codsoc " +
  4.            "and pro.fampro = 'BOUREF' " +
  5.            "and pro.codblocage = 'CTR' " +
  6.            "and fam.codsoc = pro.codsoc " +
  7.            "and fam.codefam = pro.fampro " +
  8.            "and fam.codesfa = pro.sfapro " +
  9.            "order by fam.libfam";
  10. public DataTable LoadBouFam(decimal codsoc)
  11. {
  12. if (cnx.isAvailable)
  13. {
  14.  OracleCommand cmd = cnx.CreateCommand();
  15.  cmd.CommandType = CommandType.Text;
  16.  cmd.CommandText = bouFam;
  17.  OracleParameter param1 = cmd.CreateParameter();
  18.  param1.DbType = DbType.Decimal;
  19.  param1.Direction = ParameterDirection.Input;
  20.  param1.ParameterName = ":codsoc";
  21.  param1.Size = 12;
  22.  param1.Value = codsoc;
  23.  cmd.Parameters.Add(param1);
  24.  OracleDataAdapter da = cnx.GetDataAdapter(cmd);
  25.  DataTable dt = new DataTable();
  26.  da.Fill(dt);
  27.  return dt;
  28. }
  29. else
  30. {
  31.  return null;
  32. }
  33. }


 
:sol:

Message cité 1 fois
Message édité par MagicBuzz le 25-10-2006 à 17:59:06
Reply

Marsh Posté le 25-10-2006 à 18:01:40    

Pour en revenir aux variables en SQL : moi aussi j'ai l'habitude de bosser avec des variables (je bosse sous SQL Server ces temps-ci).
Disons que, quand j'écris une requête SQL que je passe ensuite dans une variable dans un autre langage (VB, php, ...) du genre  
 
mavar = "SELECT ..."
 
ce n'est peut-être, comme tu le dis, qu'une question d'habitude, ou un avis personnel, mais je met un point d'honneur à sortir mes variables PHP de ma chaine de texte (et donc de faire comme l'exemple que j'ai mis plus haut). Histoire de bien différencier, comme je le disais, le SQL de l'autre langage de programmation, justement pour faire la part des chose entre SQL et ce qui ne l'est pas.
 
M'enfin, spa la peine de s'attarder là-dessus ! :)
 
(note : suis crevé, fin de journée oblige, donc désolé si c'est pas très clair ce pavé de texte [:joce])


---------------
Kao ..98 - Uplay (R6S) : kao98.7.62x39 - Origin (BF4, BF1) : kntkao98
Reply

Marsh Posté le 25-10-2006 à 18:04:09    

MagicBuzz a écrit :

moi je fais des :
(...)
:sol:


Moi, c'est plus du T-SQL en fait ! ;)
Mais C# (ou MC++ :??:) avec Oracle, je connais (un peu) aussi  :whistle:


Message édité par kao98 le 25-10-2006 à 18:05:11

---------------
Kao ..98 - Uplay (R6S) : kao98.7.62x39 - Origin (BF4, BF1) : kntkao98
Reply

Marsh Posté le 25-10-2006 à 19:02:30    

Ici, c'est C# avec Oracle en effet ;)

Reply

Marsh Posté le 25-10-2006 à 19:05:23    

Disons que noyer les variables PHP dans le SQL, ça permet, sans rien toucher mise à part le $ à transformer en : ou @, de passer à une syntaxe propre, à base d'objets Command et Parameters (qui évitent les erreurs de type et de SQL Injection).
C'est pour cette ressemblance que j'aime bien la syntaxe sans concaténation (plus le fait que les concaténations, moins on en fait mieux c'est, mais bon, là c'est de l'optimisation à deux balles, faut pas que ça vienne polluer la lisibilité, je suis d'accord)

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed