Postgresql и PHP: является ли currval эффективным способом получения последней вставленной строки id в многопользовательском приложении? - PullRequest
3 голосов
/ 21 мая 2009

Мне интересно, эффективен ли способ, которым я использую для получения идентификатора последней строки, вставленной в таблицу 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. Я должен знать имя последовательности таблицы. Becose pg_get_serial_sequence не работает для меня (я новичок в postgresql, вероятно, это проблема конфигурации)

Любое предложение / лучшие способы?

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

EDIT:

@ SpliFF (thet удалил его ответ): это будет работать лучше?

$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);

Ответы [ 3 ]

7 голосов
/ 21 мая 2009

Если вы используете более новую версию PostgreSQL (> 8.1), вам следует использовать предложение RETURNING команды INSERT (и UPDATE).

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

1 голос
/ 21 мая 2009

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

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

BEGIN TRANSACTION;
INSERT ...;
SELECT curval(seq);
COMMIT;
0 голосов
/ 13 октября 2010

ех. minsert в log (desc, user_id) значения ('отбросьте ее', 6) возвращая id

...