2008-11-14 6 views
6

Я всегда слышу, что использование «lastInsertId» (или mysql_insert_id(), если вы не используете PDO) является злым. В случае триггеров это очевидно, потому что он может вернуть то, что полностью не является последним идентификатором, созданным вашим INSERT.Альтернатива «PDO :: lastInsertId»/«mysql_insert_id»

$DB->exec("INSERT INTO example (column1) VALUES ('test')"); 
// Usually returns your newly created ID. 
// However when a TRIGGER inserts into another table with auto-increment: 
// -> Returns newly created ID of trigger's INSERT 
$id = $DB->lastInsertId(); 

Какая альтернатива?

ответ

2

Если вы идете по маршруту ADOdb (http://adodb.sourceforge.net/), вы можете создать идентификатор вставки перед началом работы и указать конкретный идентификатор при вставке. Это можно реализовать портативно (ADOdb поддерживает массу различных баз данных ...) и гарантирует, что вы используете правильный идентификатор вставки.

Тип данных PostgreSQL SERIAL аналогичен типу, за исключением того, что для каждой таблицы/для каждой последовательности вы указываете таблицу/последовательность, в которой вы хотите использовать последний идентификатор вставки, когда вы его запрашиваете.

+0

+1 .I написал мой ответ, как вы писали свои – 2008-11-14 14:06:00

+0

Выглядит довольно интересно. Какое влияние оказывает этот метод на производительность? – BlaM 2008-11-14 15:47:39

0

Это не сложно, и это не эффективно, но если введенные данные содержат уникальные поля, то SELECT, очевидно, может дать то, что вам нужно.

Например:

INSERT INTO example (column1) VALUES ('test'); 
SELECT id FROM example WHERE column1 = 'test'; 
+0

Очевидно, что;) - но и, очевидно, довольно уродливый;) – BlaM 2008-11-14 12:31:14

1

Я предполагаю, что это на самом деле не состояние искусства либо, но я использую блокировку записи, чтобы убедиться, что я действительно получить последний вставленный ID.

+0

Очевидно, что и работа - но блокировка IMHO еще более зла в высокопроизводительных веб-приложениях ... – BlaM 2008-11-14 13:03:08

4

IMHO считается только «злым», потому что вряд ли любая другая база данных SQL (если таковая имеется) имеет его.

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

+0

По крайней мере, MSSQL имеет ту же функцию. В моей старой работе с использованием «insert id» вызвали серьезные головные боли, когда кто-то добавил триггер к таблице, которая разбила весь сайт - без очевидной причины для тех, кто не знал об этом триггере ... – BlaM 2008-11-14 13:16:30

3

Одна из альтернатив заключается в использовании последовательностей вместо этого, поэтому вы сами генерируете идентификатор перед тем, как вставить.

К сожалению, они не поддерживаются в MySQL, но библиотеки, подобные Adodb, могут имитировать их, используя другую таблицу. Я думаю, однако, что само соревнование будет использовать lastInsertId() или эквивалент ... но, по крайней мере, вы с меньшей вероятностью иметь триггер на таблицу, которая используется исключительно для последовательности

-3

Вы можете попробовать это:

$sql = "SELECT id FROM files ORDER BY id DESC LIMIT 1"; 
$PS = $DB -> prepare($sql); 
$PS -> execute(); 
$result = $PS -> fetch();