sql >> Databasteknik >  >> RDS >> PostgreSQL

Referensvärde för seriell kolumn i en annan kolumn under samma INSERT

Du kan använda en CTE för att hämta värdet från sekvensen en gång och använd den upprepade gånger :

WITH cte AS (
   SELECT nextval('foo_id_seq') AS id
   )
INSERT INTO foo (id, ltree)
SELECT id, '1.' || id
FROM   cte;

CTE med ett datamodifierande kommando kräver Postgres 9.1 eller senare.

Om du inte är säker på namnet på sekvensen, användpg_get_serial_sequence() istället:

WITH i AS (
   SELECT nextval(pg_get_serial_sequence('foo', 'id')) AS id
   )
INSERT INTO foo (id, ltree)
SELECT id, '1.' || id
FROM   i;

Om tabellnamnet "foo" kanske inte är unikt för alla scheman i databasen, schemakvalificera det. Och om stavningen av något namn är icke-standard, måste du dubbelcitera:

pg_get_serial_sequence('"My_odd_Schema".foo', 'id')


Snabbtester indikerade @Marks idé med lastval() kanske fungerar också:

INSERT INTO foo (ltree) VALUES ('1.' || lastval());
  • Du kan bara lämna id ur frågan, serial kolumnen tilldelas automatiskt. Gör ingen skillnad.

  • Det bör inte finnas ett tävlingsförhållande mellan raderna. Jag citerar manualen:

currval

Returnera det värde som senast erhölls av nextval för denna sekvens i den aktuella sessionen. (Ett fel rapporteras om nextval har aldrig kallats för denna sekvens i den här sessionen.) Eftersom detta returnerar ett sessionslokalt värde, ger det ett förutsägbart svar om andra sessioner har exekverat nextval sedan den aktuella sessionen gjorde.

Denna funktion kräver USAGE eller SELECT privilegium på sekvensen.

lastval

Returnera det värde som senast returnerades av nextval i den aktuella sessionen. Denna funktion är identisk med currval , förutom att istället använda sekvensnamnet som ett argument hänvisar det till vilken sekvens nextval användes senast i den aktuella sessionen. Det är ett fel att anropa lastval om nextval har ännu inte anropats i den aktuella sessionen.

Denna funktion kräver USAGE eller SELECT privilegium på den senast använda sekvensen.

Djärv betoning min.

Men , som @Bernard kommenterade, det kan trots allt misslyckas:det finns ingen garanti för att standardvärdet är ifyllt (och nextval() kallas i processen) före lastval() anropas för att fylla den andra kolumnen ltree . Så håll dig till den första lösningen och nextval() för att vara säker.



  1. Oracle SQL Query för att lista alla scheman i en DB

  2. En översikt över ProxySQL-klustring i ClusterControl

  3. Använda CONTINUE In Loops för att återuppta kontrollen i Oracle

  4. Ställa in MySQL root-användarlösenordet på OS X