У меня есть таблица:
CREATE TABLE names (id serial, name varchar(20))
Я хочу "последний вставленный идентификатор" из этой таблицы, без использования RETURNING id
при вставке. Кажется, есть функция CURRVAL()
, но я не понимаю, как ее использовать.
Я пробовал с:
SELECT CURRVAL() AS id FROM names_id_seq
SELECT CURRVAL('names_id_seq')
SELECT CURRVAL('names_id_seq'::regclass)
но никто из них не работает. Как я могу использовать, currval()
чтобы получить последний вставленный идентификатор?
postgresql
sequence
Jonas
источник
источник
currval()
определенно не рекомендуется.Ответы:
Если вы создаете столбец,
serial
PostgreSQL автоматически создает последовательность для этого.Имя последовательности генерируется автоматически и всегда является tablename_columnname_seq, в вашем случае последовательность будет иметь имена
names_id_seq
.Вставив в таблицу, вы можете вызвать
currval()
с этим именем последовательности:Вместо жесткого кодирования имени последовательности, вы также можете использовать
pg_get_serial_sequence()
вместо:Таким образом, вам не нужно полагаться на стратегию именования, которую использует Postgres.
Или, если вы вообще не хотите использовать имя последовательности, используйте
lastval()
источник
currval()
в многопользовательской настройке. Например, на веб-сервере.currval()
является "локальным" для вашего текущего соединения. Таким образом, нет проблем с его использованием в многопользовательской среде. Вот и вся цель последовательности.Это прямо из переполнения стека
Как указали @a_horse_with_no_name и @Jack Douglas, currval работает только с текущим сеансом. Поэтому, если вы согласны с тем фактом, что на результат может повлиять незафиксированная транзакция другого сеанса, и вам все еще нужно что-то, что будет работать между сеансами, вы можете использовать это:
Используйте ссылку на SO для получения дополнительной информации.
Из документации Postgres ясно сказано, что
Итак, я думаю, строго говоря, чтобы правильно использовать currval или last_value для последовательности между сеансами, вам нужно сделать что-то подобное?
Предполагая, конечно, что у вас не будет вставки или любого другого способа использования последовательного поля в текущем сеансе.
источник
nextval()
, необходимо вручную установить последовательность, соответствующую количеству записей приборов, которые вы вставили, с жестко закодированными идентификаторами. Кроме того, способ решения проблемы недоступности pre-nextval функции currval () / lastval () заключается в непосредственномSELECT
использовании последовательности.Вам нужно вызвать
nextval
эту последовательность в этом сеансе доcurrval
:таким образом, вы не можете найти «последний вставленный идентификатор» из последовательности, если это
insert
не сделано в том же сеансе (транзакция может откатиться, но последовательность не будет)как указано в ответе a_horse,
create table
столбец типаserial
автоматически создаст последовательность и будет использовать ее для генерации значения по умолчанию для столбца, поэтомуinsert
обычно доступ осуществляетсяnextval
неявно:источник
Итак, есть некоторые проблемы с этими различными методами:
Currval получает только последнее значение, сгенерированное в текущем сеансе - это замечательно, если у вас больше ничего не генерируется, но в тех случаях, когда вы можете вызвать триггер и / или получить последовательность, продвинутую более одного раза в текущей транзакции, это не собираюсь возвращать правильное значение. Это не проблема для 99% людей, но это то, что нужно учитывать.
Лучший способ получить уникальный идентификатор, назначенный после операции вставки, - использовать предложение RETURNING. В приведенном ниже примере предполагается, что столбец, связанный с последовательностью, называется «id»:
Обратите внимание, что полезность предложения RETURNING выходит далеко за рамки простого получения последовательности, поскольку она также:
Вернуть значения, которые были удалены:
удалить из таблицы A, где id> 100 возвращается *
Вернуть измененные строки после ОБНОВЛЕНИЯ:
обновить таблицу Набор X = 'y', где blah = 'blech' возвращение *
Используйте результат удаления для обновления:
WITH A as (удалить * из таблицы A в качестве возвращаемого идентификатора) update B установить удалено = true, где id in (выбрать идентификатор из A);
источник
RETURNING
предложение, но нет ничего плохого в том, чтобы сделать его использование более понятным для других.Мне пришлось выполнить запрос, несмотря на использование SQLALchemy, потому что мне не удалось использовать currval.
Это был проект на python flask + postgresql.
источник
Если вы хотите получить значение последовательностей, не вызвав
nextval()
и не изменив последовательность, я собрал вместе функцию PL / pgSQL для ее обработки: найдите значение всех последовательностей базы данныхисточник
Вам нужно
GRANT
использовать схему, как это:а также
источник
currval()
функции, чтобы сделать ее более релевантной для этого потока?В PostgreSQL 11.2 вы можете рассматривать последовательность как таблицу, которая выглядит так:
Пример, если у вас есть последовательность с именем: 'names_id_seq'
Это должно дать вам последний вставленный идентификатор (в данном случае 4), что означает, что текущее значение (или значение, которое следует использовать для следующего идентификатора) должно быть 5.
источник
Разные версии PostgreSQL могут иметь разные функции для получения текущего или следующего идентификатора последовательности.
Во-первых, вы должны знать версию вашего Postgres. Используя select version (); чтобы получить версию.
В PostgreSQL 8.2.15 вы получаете текущий идентификатор последовательности с помощью
select last_value from schemaName.sequence_name
.Если приведенное выше утверждение не работает, вы можете использовать
select currval('schemaName.sequence_name');
источник