Как в PostgreSQL получить последний идентификатор, вставленный в таблицу?
В MS SQL есть SCOPE_IDENTITY ().
Пожалуйста, не советуйте мне использовать что-то вроде этого:
select max(id) from table
postgresql
insert
lastinsertid
Антон
источник
источник
Ответы:
(
tl;dr
: переход к варианту 3: вставка с возвратом)Напомним, что в postgresql отсутствует концепция «id» для таблиц, а только последовательности (которые обычно, но не обязательно, используются в качестве значений по умолчанию для суррогатных первичных ключей с псевдотипом SERIAL ).
Если вы заинтересованы в получении идентификатора недавно вставленной строки, есть несколько способов:
Вариант 1:
CURRVAL(<sequence name>);
.Например:
Имя последовательности должно быть известно, оно действительно произвольно; в этом примере мы предполагаем, что в таблице
persons
естьid
столбец, созданный сSERIAL
псевдотипом. Чтобы не полагаться на это и чувствовать себя более чистым, вы можете использовать вместо этогоpg_get_serial_sequence
:Предостережение:
currval()
работает только послеINSERT
(который выполненnextval()
), в том же сеансе .Вариант 2:
LASTVAL();
Это похоже на предыдущее, только в том, что вам не нужно указывать имя последовательности: оно ищет самую последнюю измененную последовательность (всегда внутри вашего сеанса, то же предупреждение, что и выше).
Оба
CURRVAL
иLASTVAL
полностью безопасны одновременно. Поведение последовательности в PG спроектировано таким образом, что другой сеанс не будет мешать, поэтому нет риска возникновения условий гонки (если другой сеанс вставит другую строку между моим INSERT и моим SELECT, я все равно получу правильное значение).Однако у них есть тонкая потенциальная проблема. Если в базе данных есть какой-то TRIGGER (или RULE), который при вставке в
persons
таблицу делает дополнительные вставки в другие таблицы ... тогдаLASTVAL
, вероятно, даст нам неправильное значение. Проблема может даже случитьсяCURRVAL
, если дополнительные вставки выполняются в одну и ту жеpersons
таблицу (это гораздо реже, но риск все еще существует).Вариант 3:
INSERT
сRETURNING
Это самый чистый, эффективный и безопасный способ получить удостоверение личности. Это не имеет никакого риска предыдущего.
Недостатки? Почти ничего: вам может понадобиться изменить способ вызова оператора INSERT (в худшем случае, возможно, ваш уровень API или DB не ожидает, что INSERT вернет значение); это не стандартный SQL (кого это волнует); это доступно с Postgresql 8.2 (декабрь 2006 ...)
Вывод: если можете, перейдите к варианту 3. В другом месте предпочтите 1.
Примечание: все эти методы бесполезны, если вы намерены получить последний вставленный идентификатор глобально (не обязательно с помощью вашего сеанса). Для этого вы должны прибегнуть к
SELECT max(id) FROM table
(конечно, это не будет читать незафиксированные вставки из других транзакций).И наоборот, вы никогда не должны использовать
SELECT max(id) FROM table
вместо этого один из трех вариантов выше, чтобы получить идентификатор, только что сгенерированный вашимINSERT
оператором, потому что (кроме производительности) это не безопасно одновременно: между вашимINSERT
и вашимSELECT
другим сеансом может быть вставлена другая запись.источник
SELECT max(id)
к сожалению, не выполняет работу, как только вы начинаете удалять строки.1,2,3,4,5
и вы удалите строки 4 и 5, последний вставленный идентификатор по-прежнему 5, ноmax()
возвращает 3.RETURNING id;
для вставки в другую таблицу, будет приветствоваться!RETURNING id
в сценарии SQL, поданного вpsql
инструмент командной строки?Смотрите предложение RETURNING оператора INSERT . По сути, INSERT удваивается как запрос и возвращает вам значение, которое было вставлено.
источник
insert into names (firstname, lastname) values ('john', 'smith') returning id;
то он просто выводит id так же, как если бы вы работалиselect id from names where id=$lastid
напрямую. Если вы хотите сохранить возврат в переменную aa , тоinsert into names (firstname, lastname) values ('john', 'smith') returning id into other_variable;
если оператор, содержащий возвращение, является последним оператором в функции , то редактируемый идентификаторreturning
возвращается функцией в целом.Вы можете использовать предложение RETURNING в операторе INSERT, как показано ниже
источник
Ответ Леонблоя довольно полный. Я бы добавил только тот особый случай, когда нужно получить последнее вставленное значение из функции PL / pgSQL, где ОПЦИЯ 3 не подходит точно.
Например, если у нас есть следующие таблицы:
Если нам нужно вставить запись клиента, мы должны обратиться к записи человека. Но скажем, мы хотим разработать функцию PL / pgSQL, которая вставляет новую запись в клиент, но также заботится о вставке новой записи о человеке. Для этого мы должны использовать небольшое изменение ВАРИАНТА 3 leonbloy:
Обратите внимание, что есть два предложения INTO. Следовательно, функция PL / pgSQL будет определена так:
Теперь мы можем вставить новые данные, используя:
или
И мы получаем недавно созданный идентификатор.
источник
Для тех, кому нужно получить всю запись данных, вы можете добавить
до конца вашего запроса, чтобы получить весь объект, включая идентификатор.
источник
Смотрите пример ниже
Затем для получения последнего вставленного идентификатора используйте это для таблицы "user". Seq имя столбца "id"
источник
Вам необходимо указать имя таблицы и название столбца, конечно.
Это будет для текущего сеанса / подключения http://www.postgresql.org/docs/8.3/static/functions-sequence.html.
источник
Попробуй это:
Если это вернет 1 (или что-то еще из start_value для вашей последовательности), тогда верните последовательность обратно к исходному значению, передав флаг false:
В противном случае,
Это восстановит значение последовательности в исходное состояние, а «setval» вернет значение последовательности, которое вы ищете.
источник
Postgres имеет встроенный механизм для этого, который в том же запросе возвращает идентификатор или все, что вы хотите, чтобы запрос возвращал. вот пример. Предположим, у вас есть созданная таблица, в которой есть 2 столбца column1 и column2, и вы хотите, чтобы column1 возвращалась после каждой вставки.
источник
У меня была эта проблема с Java и Postgres. Я исправил это, обновив новую версию Connector-J.
PostgreSQL-9.2-1002.jdbc4.jar
https://jdbc.postgresql.org/download.html : версия 42.2.12
https://jdbc.postgresql.org/download/postgresql-42.2.12.jar
источник