Précédent   Forum des professionnels en informatique > Bases de données > PostgreSQL
PostgreSQL Forum PostgreSQL. Avant de poster -> F.A.Q PostGreSQL Tutoriels PostGreSQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 17/10/2007, 10h23   #1
Membre régulier
 
Inscription : avril 2004
Messages : 284
Détails du profil
Informations forums :
Inscription : avril 2004
Messages : 284
Points : 75
Points : 75
Par défaut Besoin conseil pour gérer SERIAL

Bonjour,

J'aurais donc besoin d'un petit conseil :

J'ai une table qui est du style :

ma_table
id SERIAL,
nom TEXT UNIQUE NOT NULL

J'ai remarqué que si un INSERT de nom échoue, l'id est tout de même incrémenté (du coup j'ai des gaps énormes entre 2 valeurs). Comment me conseilleriez-vous de gérer ceci ?

Je pense soit :

- gestion par la base: trigger avec fonction trigger mais je ne crois pas pouvoir interrompre un INSERT, et je ne peux pas agir sur la valeur d'un SERIAL (heureusement )

- par script: une fonction qui me renverrait un booléen selon l'existence du nom et je n'effectuerai l'INSERT que dans le cas de non existence

En vous remerciant,

C. Tobini
ctobini est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/10/2007, 11h32   #2
Membre habitué
 
Inscription : août 2007
Messages : 128
Détails du profil
Informations forums :
Inscription : août 2007
Messages : 128
Points : 146
Points : 146
En quoi le gap entre deux valeurs d'une même séquence est un problème ?

Sinon, pour le reste :

Citation:
gestion par la base: trigger avec fonction trigger mais je ne crois pas pouvoir interrompre un INSERT, et je ne peux pas agir sur la valeur d'un SERIAL (heureusement )
Interrompre un INSERT est possible et vous pouvez agir sur un SERIAL. Je ne vois pas le rapport avec le problème du gap, mais ce sont des fonctionnalités disponibles.

Citation:
par script: une fonction qui me renverrait un booléen selon l'existence du nom et je n'effectuerai l'INSERT que dans le cas de non existence
Il serait plus simple dans ce cas de faire une fonction qui réaliserait tout ça. Une fonction du style

Code :
1
2
3
4
5
SELECT 1 FROM ma_table WHERE nom='le nom à insérer donné en variable à la fonction';
IF NOT FOUND
THEN
  INSERT INTO ma_table (nom) VALUES ('le nom à insérer donné en variable à la fonction');
END IF
gleu_ est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/10/2007, 14h02   #3
Membre régulier
 
Inscription : avril 2004
Messages : 284
Détails du profil
Informations forums :
Inscription : avril 2004
Messages : 284
Points : 75
Points : 75
Bonjour et merci de la réponse,

Le gap n'est pas un problème. Mais un saut de 6 000 000 entre 2 entrées (surtout qu'il n'y en a que 10), je trouve ça assez peu élégant.

Citation:
Interrompre un INSERT est possible et vous pouvez agir sur un SERIAL
C'est à dire que je peux, sur un trigger BEFORE INSERT arrêter l'INSERT ?

Pour le SERIAL, je préfère laisser gérer le système et ne pas trop jouer avec les séquences, elles sont là pour ça.

Pour la fonction c'est quelque chose comme ça que je voyais, appeler une fonction SQL via le script. J'aimerais bien néanmois gérer si c'est possible par trigger, avant insertion.

C. Tobini
ctobini est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/10/2007, 14h22   #4
Membre habitué
 
Inscription : août 2007
Messages : 128
Détails du profil
Informations forums :
Inscription : août 2007
Messages : 128
Points : 146
Points : 146
Un saut de 6000000 entre deux INSERT me paraît énorme. De quatre/cinq, je veux bien. De 6000000, j'ai un doute. Quel est le pas de ce trigger ? le meilleur moyen de le savoir est de lancer la requête suivante :

Code :
SELECT increment_by FROM la_sequence;
Pour l'annulation d'un trigger INSERT, oui, c'est possible. Il faut que le trigger soit de niveau ligne (et non pas instruction) et que ce soit un trigger BEFORE. Il convient simplement de renvoyer NULL pour que l'opération soit annulée. Ceci est aussi vrai pour un trigger UPDATE.

Pour la fonction, c'était du PL/pgsql, donc pas forcément supportée sur la base utilisée.
gleu_ est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/10/2007, 16h38   #5
Membre régulier
 
Inscription : avril 2004
Messages : 284
Détails du profil
Informations forums :
Inscription : avril 2004
Messages : 284
Points : 75
Points : 75
Citation:
Un saut de 6000000 entre deux INSERT me paraît énorme...
Oui, j'ai fait du ligne à ligne sur 10 fichiers de 6 000 000 de lignes en injectant le nom du fichier à chaque ligne au lieu de le faire en début de code (précipitation)... c'est ballot, mais maintenant que j'ai intégré les 60 000 000 de données, je ne vais pas relancer

Citation:
Pour l'annulation d'un trigger INSERT, oui, c'est possible. Il faut que le trigger soit de niveau ligne (et non pas instruction) et que ce soit un trigger BEFORE. Il convient simplement de renvoyer NULL pour que l'opération soit annulée.
Je vais tester, c'est juste un RETURN NULL qui annule l'insertion sur un trigger FOR EACH ROW à ce moment ?

C. Tobini
ctobini est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/10/2007, 17h44   #6
Membre habitué
 
Inscription : août 2007
Messages : 128
Détails du profil
Informations forums :
Inscription : août 2007
Messages : 128
Points : 146
Points : 146
En fait, la ligne renvoyée est la ligne insérée. Dans le cas où la procédure trigger renvoit NULL, cela annule l'opération (donc l'insertion).
gleu_ est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/10/2007, 13h58   #7
Membre régulier
 
Inscription : avril 2004
Messages : 284
Détails du profil
Informations forums :
Inscription : avril 2004
Messages : 284
Points : 75
Points : 75
OK merci, je vais tester cette solution !

Bon week-end,

C. Tobini
ctobini est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 00h20.


 
 
 
 
Partenaires

Hébergement Web