2009-03-07 3 views
16

Каков наилучший способ получить значение auto-id в том же SQL с помощью SELECT?SQL - INSERT и поймать значение автоинкремента id

В форуме говорится, что добавление этого слова «; has Return Scope_Identity()»
в конце SQL работает в ASP.

Есть ли соответствующий способ в PHP?

+0

Этот вопрос имеет отношение ко всему, что использует SQL, а не только PHP. –

ответ

16

Это зависит от вашего сервера базы данных. Используя MySQL, позвоните по номеру mysql_insert_id() сразу же после запроса на ввод. Используя PostgreSQL, сначала запросите «select nextval(seq)» в последовательности и включите ключ в ваш запрос на вставку.

Запрос на "select max(id) + 1 from tbl" может завершиться неудачно, если другой запрос вставляет запись одновременно.

0

В PHP: mysql_insert_id() http://us3.php.net/mysql_insert_id

или

Если вы хотите, чтобы genterate номер с вашего MYSQL выбора запроса, вы можете использовать этот EDIT:

SELECT LAST_INSERT_ID(`1`) + 1 FROM table 
+0

Выбор max может быть проблемой, если несколько процессов делают вставки, не так ли? – schooner

+1

, если вы вставляете запись, а затем удаляете запись, а затем запускаете этот запрос, вы получите идентификатор удаленной записи. следующая вставка не получит эту идентификацию в любой реализации, о которой я знаю. Избегайте этого любой ценой ... – MatBailie

+0

вы должны поместить блокировку чтения на стол, если вы хотите, чтобы это было безопасно! даже тогда я не уверен, что СУБД не будет повторно использовать какой-либо удаленный идентификатор, если в таблице существует пробел. –

3

Это зависит от используемого устройства базы данных. Например, в некоторых СУБД, например Firebird, есть предложение RETURNING, которое вы можете добавить к вашему запросу. Например, если у вас есть таблица с именем TABLE1 колонке с автоинкремент именем ID, вы можете использовать это:

insert into TABLE1(columns...) values (values...) returning ID; 

И было бы вернуть вставленный ID как обычный выберите заявление.

0

Будьте очень осторожны: очевидно, что nextval (seq) не работает в высоком параллелизме - некоторое другое соединение может вставляться между временем, когда вы вставили, и временем, когда вы вызывали select nextval (seq). Всегда проверяйте такой код в жгутах с высокой параллельной проверкой.

+0

Это не имеет значения, если вы не используете идентификатор для заказа, потому что вы используете результат nextval (seq), а не другой вызов самой последовательности. –

2

В Microsoft Transact SQL вы можете использовать @@ IDENTITY.

например.

DECLARE @Table TABLE (col0 INT IDENTITY, col1 VARCHAR(255), col2 VARCHAR(255)) 

INSERT INTO @Table (col1, col2) VALUES ('Hello','World!') 

SELECT @@Identity 

SELECT * FROM @Table 
+1

никогда не используйте @ @ identity, это не всегда даст вам правильное значение идентификатора и может вызвать очень плохие проблемы с целостностью данных. Используйте scope_identity() – HLGEM

+0

Ну, @ @ identity - это нормально, если вы знаете, что он делает, и объем его эффекта. Просто будьте осторожны, если у вас есть триггеры на таблицах (вставка в таблицу с столбцом идентификации в триггере приведет к обновлению идентификатора @@) или если репликация таблицы. Хорошо, вероятно, безопаснее использовать scope_identity() :) – Jon

0

В SQL Server вставки с помощью оператора выбора может иметь условие вывода, которая будет возвращать значение идентификатора и любые другие столбцы, которые вы, возможно, потребуется определить, какая личность переходит к которой запись. Если вы используете предложение values, используйте select scope_identity() сразу после вставки.

7

В Postgres лучший способ сделать что-то вроде:

insert into foos(name) values ('my_foo') returning id; 
Смежные вопросы