Скажем, у меня есть следующие данные в таблице клиентов: (ничто больше)
ID FirstName LastName
-------------------------------
20 John Mackenzie
21 Ted Green
22 Marcy Nate
Какой SELECT
оператор может получить меня номер 22 в столбце ID?
Я должен сделать что-то вроде этого для генерации уникального идентификатора. Уверенный я могу позволить системе сделать это через автоинкремент, но затем как я получил бы автоматический сгенерированный идентификатор?
Я думал SELECT ID FROM Customers
и подсчет возвращенных строк, но это кажется ужасно неэффективным, и в этом случае, он неправильно возвратится "3", хотя мне нужен уникальный идентификатор 23.
Зависит от того, какую реализацию SQL вы используете. Например, и MySQL, и SQLite имеют способы получить идентификатор последней вставки. Фактически, если вы используете PHP, есть даже отличная функция именно для этого mysql_insert_id ().
Вам, вероятно, следует использовать эту функцию MySQL вместо просмотра всех строк, чтобы получить самый большой идентификатор вставки. Если ваш стол станет большим, это может стать очень неэффективным.
Если вы не используете автоматически увеличивающиеся поля, вы можете добиться аналогичного результата примерно следующим образом:
insert into Customers (ID, FirstName, LastName)
select max(ID)+1, 'Barack', 'Obama' from Customers;
Это гарантирует отсутствие шансов на возникновение состояния гонки, которое могло быть вызвано кто-то другой вставляет в таблицу между извлечением максимального идентификатора и вставкой новой записи.
Это использование стандартного SQL, без сомнения, есть лучшие способы достижения этого с помощью конкретной СУБД », но они не обязательно портативный (то, к чему мы очень серьезно относимся в нашем магазине).
Если вы говорите о MS SQL, вот самый эффективный способ. Это извлекает текущее начальное значение идентификатора из таблицы на основе того, какой столбец является идентификатором.
select IDENT_CURRENT('TableName') as LastIdentity
Использование MAX (id)
является более общим, но, например, у меня есть таблица с 400 миллионами строк, которая занимает 2 минуты чтобы получить MAX (id)
. IDENT_CURRENT
почти мгновенно ...
Если вы используете AUTOINCREMENT
, используйте:
SELECT LAST\_INSERT\_ID();
Предполагая, что вы используете Mysql: http://dev.mysql.com/doc/refman/5.0/en/example-auto-increment.html
Postgres обрабатывает это аналогичным образом с помощью функции currval (sequence_name)
.
Обратите внимание, что использование MAX (ID)
небезопасно, если вы не заблокируете таблицу, поскольку возможно (в упрощенном случае) иметь еще одну вставку, которая выполняется до вызова MAX (ID)
и вы теряете идентификатор первой вставки. Вышеупомянутые функции основаны на сеансе, поэтому, если вставляется другой сеанс, вы все равно получите вставленный идентификатор.
Чтобы получить его в любое время, вы можете выполнить SELECT MAX (Id) FROM Customers
.
Однако в процедуре, которую вы добавляете, вы также можете используйте SCOPE_IDENTITY
- чтобы получить идентификатор, последний добавленный этой процедурой.
Это безопаснее, потому что это гарантирует, что вы получите свой идентификатор
- на тот случай, если в базу данных одновременно будут добавлены другие.
Если вы только что вставили запись в таблицу Customers и вам нужно значение недавно заполненного поля идентификатора, вы можете использовать функцию SCOPE_IDENTITY
. Это полезно только тогда, когда INSERT
произошло в той же области, что и вызов SCOPE_IDENTITY
.
INSERT INTO Customers(ID, FirstName, LastName)
Values
(23, 'Bob', 'Smith')
SET @mostRecentId = SCOPE_IDENTITY()
Это может быть полезно или не может быть полезно для вас, но это хороший способ быть в курсе. Он также будет работать с автоматически созданными столбцами.