PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

PostgreSQL функция за последно въведен ID

( tl;dr :отидете на опция 3:INSERT с RETURNING )

Припомнете си, че в postgresql няма концепция "id" за таблици, а само последователности (които обикновено, но не непременно се използват като стойности по подразбиране за сурогатни първични ключове, с псевдотип SERIAL).

Ако се интересувате да получите идентификатора на нововмъкнат ред, има няколко начина:

Опция 1:CURRVAL(<sequence name>); .

Например:

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

Името на последователността трябва да се знае, наистина е произволно; в този пример приемаме, че таблицата persons има id колона, създадена с SERIAL псевдотип. За да не разчитате на това и да се чувствате по-чисти, можете да използвате вместо това pg_get_serial_sequence :

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

Предупреждение:currval() работи само след INSERT (който е изпълнил nextval() ),в същата сесия .

Опция 2:LASTVAL();

Това е подобно на предишното, само че не е необходимо да указвате името на последователността:той търси най-новата модифицирана последователност (винаги във вашата сесия, същото предупреждение като по-горе).

И двете CURRVAL и LASTVAL са напълно безопасни едновременно. Поведението на последователността в PG е проектирано така, че различната сесия да не пречи, така че няма риск от условия на състезание (ако друга сесия вмъкне друг ред между моя INSERT и моя SELECT, все пак получавам правилната си стойност).

Въпреки това те имат тънък потенциален проблем. Ако базата данни има някакъв TRIGGER (или ПРАВИЛО), който при вмъкване в persons таблица, прави някои допълнителни вмъквания в други таблици... след това LASTVAL вероятно ще ни даде грешна стойност. Проблемът може да възникне дори с CURRVAL , ако допълнителните вмъквания са направени в едни и същи persons таблица (това е много по-рядко срещано, но рискът все още съществува).

Вариант 3:INSERT с RETURNING

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

Това е най-чистият, ефективен и безопасен начин за получаване на идентификатора. То няма нито един от рисковете на предишния.

Недостатъци? Почти никакъв:може да се наложи да промените начина, по който извиквате своя INSERT израз (в най-лошия случай, може би вашият API или DB слой не очаква INSERT да върне стойност); това не е стандартен SQL (на кой му пука); наличен е от Postgresql 8.2 (декември 2006 г....)

Заключение:Ако можете, изберете вариант 3. На друго място предпочитайте 1.

Забележка:всички тези методи са безполезни, ако възнамерявате да получите последния вмъкнат идентификатор глобално (не е задължително от вашата сесия). За това трябва да прибягвате до SELECT max(id) FROM table (разбира се, това няма да чете незаети вмъквания от други транзакции).

И обратното, не трябва никога използвайте SELECT max(id) FROM table вместо една от 3-те опции по-горе, за да получите току-що генерирания идентификатор от вашия INSERT изявление, защото (освен производителността) това не е едновременно безопасно:между вашия INSERT и вашият SELECT друга сесия може да е вмъкнала друг запис.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Относно въздействието на писане на цяла страница

  2. Какво е новото в PostgreSQL 12

  3. Таблица за представяне за PostgreSQL

  4. Избягване на блокиране на PostgreSQL при извършване на операции за групово актуализиране и изтриване

  5. Как да инсталирате Haproxy и Keepalived