2008-09-29 32 views
11

En SQL, ¿cómo se actualiza una tabla, estableciendo una columna con un valor diferente para cada fila?¿Cómo actualizar valores únicos en SQL usando una secuencia de PostgreSQL?

Quiero actualizar algunas filas en una base de datos PostgreSQL, estableciendo una columna en un número de una secuencia, donde esa columna tiene una restricción única. Tenía la esperanza de que así que podría utilizar:

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

pero parece que nextval sólo se le llama una vez, por lo que la actualización utiliza el mismo número para cada fila, y me da una 'llave duplicada viola restricción única' error . ¿Qué debería hacer?

Respuesta

28

No utilice una subselección, en lugar utilizar la función nextval directamente como aquí:

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

Gracias - eso funciona. Me atrapó la sub selección porque estaba tratando de usar el mismo número de secuencia para dos columnas, pero realmente no necesito hacer eso. –

+0

Si desea volver a utilizar el mismo valor de secuencia después de haber llamado a nextval ('secuencia'), puede usar la función relacionada currval ('secuencia'), que devuelve la secuencia actual. – cms

0

considero secuencias de PG es un Hack y signos que los enteros incrementales no son la mejor manera de filas clave. Aunque pgsql no recibieron soporte nativo para UUID hasta 8,3

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

Los beneficios de UUID es que la combinación son casi infinitas, a diferencia de un número aleatorio que llegará a una colisión de un día.

+0

"Casi infinito?" Los documentos dicen que es un tipo entero de 128 bits. Eso es mucho, pero no es infinito, y es casi seguro que colisione antes de que se utilicen todos los valores de 2^128. Además, los ORM probablemente tendrán que convertir a/de los tipos de cadena para usar esto. No es una victoria clara en mi opinión. – wberry

+2

Creo que subestimes qué tan grande es 2^128, lee acerca de uuid en Wikipedia. – TravisO

+0

Es principalmente académico, pero una secuencia de Postgres puede ser más a prueba de colisiones que un UUID según cómo se cree. El módulo 'uuid' de Python usa un componente aleatorio, pero sustancialmente menos de 128 bits aleatorios. Las secuencias solo colisionan si hacen ciclos, los números aleatorios colisionan ... al azar. – wberry

Cuestiones relacionadas