sql >> Databáze >  >> RDS >> PostgreSQL

PostgreSQL funkce pro poslední vložené ID

( tl;dr :přejděte na možnost 3:INSERT with RETURNING )

Připomeňme, že v postgresql neexistuje žádný koncept „id“ pro tabulky, pouze sekvence (které se obvykle, ale ne nutně, používají jako výchozí hodnoty pro náhradní primární klíče s pseudotypem SERIAL).

Pokud máte zájem získat ID nově vloženého řádku, existuje několik způsobů:

Možnost 1:CURRVAL(<sequence name>); .

Například:

  INSERT INTO persons (lastname,firstname) VALUES ('Smith', 'John');
  SELECT currval('persons_id_seq');

Název sekvence musí být znám, je opravdu libovolný; v tomto příkladu předpokládáme, že tabulka personsid sloupec vytvořený pomocí SERIAL pseudotyp. Abyste se na to nespoléhali a abyste se cítili čistěji, můžete místo toho použít pg_get_serial_sequence :

  INSERT INTO persons (lastname,firstname) VALUES ('Smith', 'John');
  SELECT currval(pg_get_serial_sequence('persons','id'));

Upozornění:currval() funguje pouze po INSERT (který provedl nextval() ), ve stejné relaci .

Možnost 2:LASTVAL();

Toto je podobné předchozímu, jen nemusíte specifikovat název sekvence:hledá nejnovější upravenou sekvenci (vždy uvnitř vaší relace, stejné upozornění jako výše).

Oba CURRVAL a LASTVAL jsou současně zcela bezpečné. Chování sekvence v PG je navrženo tak, že různé relace nebudou rušit, takže nehrozí žádné závodní podmínky (pokud jiná relace vloží další řádek mezi můj INSERT a můj SELECT, stále dostanu svou správnou hodnotu).

Nicméně mají jemný potenciální problém. Pokud má databáze nějaký SPUŠTĚČ (nebo PRAVIDLO), který při vložení do persons table, provede nějaké další vložení do jiných tabulek... pak LASTVAL pravděpodobně nám dá špatnou hodnotu. Problém může dokonce nastat s CURRVAL , pokud jsou další vkládání prováděna do stejných persons tabulka (toto je mnohem méně obvyklé, ale riziko stále existuje).

Možnost 3:INSERT s RETURNING

INSERT INTO persons (lastname,firstname) VALUES ('Smith', 'John') RETURNING id;

Toto je nejčistší, nejúčinnější a nejbezpečnější způsob, jak získat ID. Nemá žádná rizika předchozího.

Nevýhody? Téměř žádné:možná budete muset upravit způsob, jakým voláte příkaz INSERT (v nejhorším případě možná vaše vrstva API nebo DB neočekává, že INSERT vrátí hodnotu); není to standardní SQL (koho to zajímá); je k dispozici od Postgresql 8.2 (prosinec 2006...)

Závěr:Pokud můžete, přejděte na možnost 3. Jinde preferujte 1.

Poznámka:všechny tyto metody jsou k ničemu, pokud máte v úmyslu získat poslední vložené id globálně (ne nutně vaší relací). K tomu se musíte uchýlit k SELECT max(id) FROM table (samozřejmě to nebude číst nepotvrzené vložky z jiných transakcí).

Naopak byste neměli nikdy použijte SELECT max(id) FROM table místo jedné ze 3 výše uvedených možností, abyste získali ID právě vygenerované vaším INSERT prohlášení, protože (kromě výkonu) to není souběžné bezpečné:mezi vaším INSERT a váš SELECT jiná relace mohla vložit další záznam.



  1. Uspořádejte si domácí kancelář pro zvýšení produktivity

  2. Jak vybrat z MySQL, kde je název tabulky Variabilní

  3. Vyberte řádky, které nejsou přítomny v jiné tabulce

  4. 2 způsoby, jak vrátit název serveru v SQL Server (T-SQL)