Forum Programmation.php PHP, PDO, Postgresql, SERIAL, et DEFAULT

Posté par  .
Étiquettes :
0
19
juil.
2010
Dans le cadre du développement d'un site web en php, je suis passé de sqlite à postgresql pour plein de bonnes raisons.

Comme j'ai vu qu'il était conseillé d'utiliser PDO, j'ai utilisé PDO, et la transition s'est très bien effectuée, à une condition près.

Il n'y a pas de autoincrement en postgresql, mais un nom raccourci qui se nomme serial. Rien de bien compliqué là dedans, par contre, pour que le serial se déclenche, il faut mettre le mot clef default, et pas null.

Si il y en a un qui a réussi à mettre le mot clef «default» de postgresql dans un argument d'une requête préparée par PDO, qu'il se déclare. Il aura la chance d'être la première référence dans un célèbre moteur de recherche.

Car entre PDO::PARAM_INT, PDO::PARAM_STR, et PDO::PARAM_NULL, il manque un PDO::PARAM_GROAW_RAF_DE_TA_CONVERSION

Merci pour toute aide éventuelle.
  • # nextval()

    Posté par  . Évalué à 1.

    Si mes souvenirs sont bons, il fallait, à l'époque, utiliser la fonction nextval() avec en paramètre le nom de ta séquence correspondant à ton serial.

    Je suppose qu'avec PDO, tu dois pouvoir utiliser la même chose directement dans ta chaînes sans essayer de binder avec une variable et un type.

    Si vous n'aimez pas ce commentaire c'est qu'il est ironique.

    • [^] # Re: nextval()

      Posté par  . Évalué à 2.

      Le problème est au niveau du bind. J'aimerais mettre un attribut «default» dans un bind, pour éviter de devoir faire deux requêtes. Mais plus ça va, plus j'ai l'impression que je vais devoir en écrire deux… C'est moche, mais je n'ai pas le choix…

      Envoyé depuis mon lapin.

    • [^] # Re: nextval()

      Posté par  . Évalué à 1.

      Il faut utiliser une séquence et la fonction nextval() :

      CREATE SEQUENCE my_seq
      INCREMENT BY 1
      NO MAXVALUE
      NO MINVALUE
      CACHE 1;

      CREATE TABLE test(
      test_id integer NOT NULL DEFAULT nextval('my_seq'::regclass),
      test_val text
      );

      insert into test (test_val) VALUES ('1');
      insert into test (test_val) VALUES ('2');
      insert into test (test_val) VALUES ('3');

      select * from test;

      test_id | test_val
      1 | 1
      2 | 2
      3 | 3


      Par contre il faut toujours laisser la valeur par défaut. Si tu rentres une valeur à la main, la séquence ne va pas suivre.
      • [^] # Re: nextval()

        Posté par  . Évalué à 2.

        Si c'est ça, ça règle le problème. Je vais vite remplacer l'auto-increment par un (select max(id) from table), ou passer sur oracle (après sqlite et mysql).

        Envoyé depuis mon lapin.

        • [^] # Re: nextval()

          Posté par  . Évalué à 1.

          Plus d'informations et de fonctions dans la doc :
          http://docs.postgresqlfr.org/8.3/functions-sequence.html
        • [^] # Re: nextval()

          Posté par  (site web personnel) . Évalué à 1.

          Sauf qu'un (select max(id) from table) ne fonctionnera que si tu lockes complètement la table à chaque fois. Sinon, ça te ramènera sans problème deux valeurs identiques dans deux transactions différentes dès que tu auras un certain débit de transactions.

          C'est tout l'intérêt des séquences qui ne sont pas transactionnelles.

          Ceci dit, un serial crée automatiquement une séquence associée _et_ la valeur par défaut qui va bien.
          Pourquoi veux-tu préciser la valeur du champ dans ta requête ? Si tu ne le mets pas dans la requête, il prendra automatiquement la valeur par défaut. Je veux bien que _default_ soit utile parfois mais, là, je pense que tu peux t'en passer.

          Et si jamais tu veux absolument mettre le _default_, pourquoi le mettre dans les paramètres alors que ça n'en est pas un ? Met le directement dans le texte de la requête.
          • [^] # Re: nextval()

            Posté par  . Évalué à 2.

            En fait, je voulais faire en sorte que l'on puisse définir l'id, si l'on en a envi. Ce qui explique pourquoi je voulais mettre default ou une valeur dans la requête, et utiliser les binds.

            Avec sqlite, ça fonctionne très bien, car cela prends toujours l'id le plus grand plus un. Par exemple, si on laisse null pour trois insertions, on aura les valeurs 1,2, et 3. Si on rajoute une quatrième valeur avec un id que l'on décide à 999, la cinquième avec un null aura un id de 1000.

            Mais sqlite fait un gros lock sur toute la base, et n'est pas du tout adapté à ce que je veut faire. En plus des limitations volontaires du SGBD.

            Effectivement, faire un système de lock dans postgresql va être assez embêtant. Je vais peut-être revoir ma copie, en ne mettant pas de possibilité de choisir son id.

            Envoyé depuis mon lapin.

            • [^] # Re: nextval()

              Posté par  . Évalué à 1.

              Un petit peu tordu comme solution à mon avis: ajouter un trigger à l'insertion qui met à jour la valeur de la séquence si elle ne correspond pas (id précisé à la main) en utilisant les fonctions currval() et setval()
            • [^] # Re: nextval()

              Posté par  (site web personnel) . Évalué à 1.

              Effectivement, faire un système de lock dans postgresql va être assez embêtant. Je vais peut-être revoir ma copie, en ne mettant pas de possibilité de choisir son id.

              Oui, ce n'est clairement pas l'idée du siècle de laisser l'utilisateur libre de choisir l'id. S'il choisit la valeur maximale de ta séquence - 1, ça va vite être pénible...
  • # Une seule raison ...

    Posté par  . Évalué à 0.

    Pas d'auto-incrément ?

    Ben voila, tout plein de (une) bonnes raisons de passer à mysql alors :-p

    Je sais, moinssez-moi, je le mérite ...
  • # Commentaire supprimé

    Posté par  . Évalué à -2.

    Ce commentaire a été supprimé par l’équipe de modération.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.