Postgresql и PHP:является ли currval эффективным способом извлечения идентификатора последней вставленной строки в многопользовательском приложении?

StackOverflow https://stackoverflow.com/questions/892200

  •  23-08-2019
  •  | 
  •  

Вопрос

Мне интересно, эффективен ли способ, который я использую для извлечения идентификатора последней строки, вставленной в таблицу postgresql..

Очевидно, что это работает, но ссылка на значение последовательной последовательности currval может быть проблематичной, когда у меня много пользователей, добавляющих строки в одну и ту же таблицу одновременно.

Мой настоящий путь таков:

$pgConnection = pg_connect('host=127.0.0.1 dbname=test user=myuser password=xxxxx')or die('cant connect');

$insert = pg_query("INSERT INTO customer (name) VALUES ('blabla')");
$last_id_query = pg_query("SELECT currval('customer_id_seq')");
$last_id_results = pg_fetch_assoc($last_id_query);
print_r($last_id_results);
pg_close($pgConnection);

Ну, это всего лишь тестовый банкомат.Но в любом случае, я вижу 3 проблемы с этим способом:

  1. Ссылка на customer_id_seq, если два пользователя делают одно и то же в одно и то же время, может случиться так, что они оба получат один и тот же идентификатор таким образом...или нет?
  2. Я должен знать имя последовательности таблицы.Потому что pg_get_serial_sequence у меня не работает (я новичок в postgresql, вероятно, проблема с конфигурацией)

Есть какие-нибудь предложения / способы получше?

p.s:я не могу использовать PDO, потому что, похоже, немного не хватает точки сохранения транзакции;Я не буду использовать zend и, в конце концов, я предпочту использовать функции php pg_ * (возможно, я создам свои классы в конце)

Редактировать:

@SpliFF(тет удалил свой ответ):это сработало бы лучше?

$pgConnection = pg_connect('host=127.0.0.1 dbname=test user=myuser password=xxxxx')or die('cant connect');

pg_query("BEGIN");

$insert = pg_query("INSERT INTO customer (name) VALUES ('blabla')");

$last_id_query = pg_query("SELECT currval('customer_id_seq')");

$last_id_results = pg_fetch_assoc($last_id_query);

print_r($last_id_results);

//do somethings with the new customer id

pg_query("COMMIT");

pg_close($pgConnection);
Это было полезно?

Решение

Если вы используете более новую версию PostgreSQL (> 8.1), вам следует использовать ВОЗВРАЩАЕМОЕ предложение команды INSERT (и UPDATE).

OTOH если вы настаиваете на использовании одной из функций манипулирования последовательностью, пожалуйста, прочтите прекрасное руководство.Указатель:"Обратите внимание, что, поскольку это возвращает локальное значение сеанса, это дает предсказуемый ответ, выполняли ли другие сеансы nextval или нет с момента выполнения текущего сеанса".

Другие советы

Вставьте и проверьте curval (seq) внутри одной транзакции.Перед фиксацией транзакции вы увидите curval (seq) для вашего запроса и независимо от того, кто еще вставил его одновременно.

Не помню точно синтаксис - почитайте в руководстве (последний раз использовал pgsql около 3 лет назад), но в целом это выглядит так:

BEGIN TRANSACTION;
INSERT ...;
SELECT curval(seq);
COMMIT;

бывший.повторно введите значения журнала (desc, user_id) ('отбросьте ее мысли', 6), возвращающие идентификатор

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top