2008-09-29 6 views
11

En SQL, comment mettre à jour une table, en définissant une colonne à une valeur différente pour chaque ligne? Je souhaite mettre à jour certaines lignes dans une base de données PostgreSQL, en définissant une colonne sur un nombre d'une séquence, où cette colonne a une contrainte unique. J'espérais que je pouvais utiliser:Comment mettre à jour des valeurs uniques dans SQL en utilisant une séquence PostgreSQL?

update person set unique_number = (select nextval('number_sequence')); 

mais il semble que nextval est appelée une seule fois, de sorte que la mise à jour utilise le même numéro pour chaque ligne, et je reçois une « clé en double violation contrainte unique » erreur . Que devrais-je faire à la place?

Répondre

28

Ne pas utiliser une sous-sélection, utilisez plutôt la fonction nextval directement, comme ceci:

update person set unique_number = nextval('number_sequence'); 
+0

Merci - cela fonctionne. J'ai été attrapé par le sous-select parce que j'essayais d'utiliser le même numéro de séquence pour deux colonnes, mais je n'ai pas vraiment besoin de faire ça. –

+0

Si vous souhaitez réutiliser la même valeur de séquence après avoir appelé nextval ('sequence'), vous pouvez utiliser la fonction connexe currval ('sequence'), qui renvoie la séquence en cours. – cms

0

Je considère que les séquences pg un hack et des signes entiers supplémentaires ne sont pas la meilleure façon de les lignes principales. Bien que pgsql n'a pas obtenu le soutien natif pour les UUID jusqu'à 8,3

http://www.postgresql.org/docs/8.3/interactive/datatype-uuid.html

Les avantages de UUID est que la combinaison sont presque infinies, à la différence d'un nombre aléatoire qui frappera une collision un jour.

+0

"Presque infini?" Les docs disent que c'est un type entier de 128 bits. C'est beaucoup, mais ce n'est pas infini, et il est presque certain d'entrer en collision avant que toutes les 2^128 valeurs soient utilisées. De plus, les ORM devront probablement convertir vers/à partir de types de chaînes pour l'utiliser. Pas une victoire claire à mon avis. – wberry

+2

Je pense que vous avez sous-estimé la taille de 2^128, allez lire sur uuid sur Wikipedia. – TravisO

+0

Il est principalement académique, mais une séquence Postgres peut être plus résistante aux collisions qu'un UUID en fonction de sa création. Le module 'uuid' de Python utilise une composante aléatoire, mais sensiblement moins de 128 bits aléatoires. Les séquences ne s'entrechoquent que si elles sont en cycle, les nombres aléatoires entrent en collision ... de manière aléatoire. – wberry

Questions connexes