Как я могу вернуть автогенерированный ID для новой записи, которую я только что вставил? (Использование ASP классический и MSSQL 2005)получить новый идентификатор записи SQL
ответ
Спасибо всем, кто предложил SELECT SCOPE_IDENTITY(). Я был в состоянии создать хранимую процедуру:
USE [dbname]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[spInsert]
(
@Nn varchar(30)
)
AS
BEGIN TRANSACTION InsertRecord
INSERT INTO A (Nn)
VALUES (@Nn)
SELECT NewID = SCOPE_IDENTITY() -- returns the new record ID of this transaction
COMMIT TRANSACTION InsertRecord
и вызвать sproc с помощью VB:
Dim strNn '<- var to be passed'
Set cn = Server.CreateObject("ADODB.Connection")
connectString = "DSN"
cn.Open connectString, "user", "PW0rd"
Set rs = Server.CreateObject("ADODB.Recordset")
set rs = cn.Execute("EXEC [dbname].[dbo].[A] @Nn=" & strNn)
'return the value'
resultID = rs(0)
теперь я могу использовать resultID в любое время я сослаться на вновь созданный ID.
SELECT SCOPE_IDENTITY()
с помощью @@ IDENTITY может привести к неожиданным результатам, так что будьте осторожны, как вы используете, что один. Триггеры, которые вставляют записи в другие таблицы, изменят значение @@ IDENTITY - где SCOPE_IDENTITY() предоставит вам последнее удостоверение только из вашей текущей области.
Вот образец, который будет показывать разницу между @@ IDENTITY и SCOPE_INSERT(), и как они могут возвращать разные значения ..
use tempdb
go
create table table1
(ID int identity)
go
create table table2
(ID int identity(100, 1))
go
create trigger temptrig
on table1
for insert
as
begin
insert table2
default values;
end
go
insert table1
default values;
select SCOPE_IDENTITY(),
@@IDENTITY
Другой вариант, что никто не обсуждал здесь использовать предложение OUTPUT то есть в SQL 2005. В этом случае вам просто нужно добавить предложение вывода к своей вставке, а затем поймать этот набор записей из вашего кода. Это хорошо работает при вставке нескольких записей, а не только 1 ...
use tempdb
go
create table table1
(ID int identity)
go
insert table1
output inserted.ID
default values;
--OR...
insert table1
output inserted.$identity
default values;
SELECT @@ IDENTITY обычно работает, но может вернуть идентификатор записи, вставленной из триггера или что-то, а не оригинал.
SELECT SCOPE_IDENTITY - это то, что я рекомендую. Он возвращает значения, вставленные только в пределах текущей области.
Существует также IDENT_CURRENT (имя_таблицы) ", который возвращает последний идентификатор, вставленный для конкретной таблицы.
SELECT @@ Identity или SELECT SCOPE_IDENTITY() оба работают, однако выбор SCOPE_Identity() безопаснее, поскольку он возвращает последний автоматически сгенерированный идентификатор в пределах текущей области. Например, предположим, что у нас есть таблица под названием ScopeIDTable, и в этой таблице есть триггер. Этот триггер будет вставляться в запись в TriggerIdTable, обе таблицы имеют столбец автоматического увеличения.
Если вы используете SELECT @@ Identity, вы получите последний автоинкремент в этом сеансе, который будет идентификатором, сгенерированным с помощью триггера (TriggerIdTable).
Если вы используете SELECT SCOPE_IDENTITY(), вы получите идентификатор из своего ScopeIdTable.
Есть три способа, чтобы получить последнее тождество в sql.
Они уже были упомянуты другие, но для полноты картины:
- @@ IDENTITY - может также возвращать идентификаторы, созданные в других объектов в том же объеме (думаю, спусковые)
- IDENT_CURRENT - ограничен таблицу, но не для вашей области действия, поэтому она может давать плохие результаты для занятых таблиц
- Scope_Idenity() - Ограничение объема запроса.Используйте 99% времени
Кроме того, есть три способа, чтобы принять этот идентификатор и вернуть его в код клиента:
использовать выходной параметр в хранимой процедуре
INSERT INTO [MyTable] ([col1],[col2],[col3]) VALUES (1,2,3); SELECT @OutputParameterName = Scope_Identity();
Используйте возвращаемое значение.
INSERT INTO [MyTable] ([col1],[col2],[col3]) VALUES (1,2,3); Return Scope_Identity();
Выберите идентификатор в результирующий набор. Например, ваш SQL заявление будет выглядеть примерно так:
Dim ResultID As Integer Dim strSQL As String strSQL = "INSERT INTO [MyTable] ([col1],[col2],[col3]) VALUES (1,2,3); SELECT Scope_Identity();" rsResults.Open strSQL, oConn ResultID = rsResults("ID")
К сожалению (или к счастью, с моей точки зрения) мой классический ASP это слишком далеко, чтобы показать примеры первых двух из клиентского кода ,
Вы запускаете запрос
select scope_identity()
с использованием того же соединения с базой данных, прежде чем делать что-нибудь еще с ним. В результате, как вы, вероятно, ожидаете, набор записей, содержащий одну строку, которая имеет одно поле. Вы можете получить доступ к полю, используя индекс 0, или вы можете дать ему имя, если вы предпочитаете:
select scope_identity() as lastId
Где нужно вставить сразу в моде на основе набора несколько записей, он может получить более интересным.
Иногда я использовал GUID, созданный клиентами (но для классического ASP вам, вероятно, потребуется использовать служебную программу для генерации значений) или, чаще всего, ограничение NEWSQUENTIALID() в столбце ключа GUID на сервере.
Я знаю не всех, как GIUDS, хотя по некоторым вполне обоснованным причинам (их размер и то, как он влияет на индексирование/пейджинг для одного).
http://www.sqlmag.com/Articles/Index.cfm?ArticleID=50164&pg=2
Я всегда задавался вопросом, почему можно было бы когда-либо хотели бы использовать
@@identity
так
select scope_identity()
, очевидно, является самым экономить способ сделать то, что шотландец просит.
спасибо всем, кто предложил SELECT SCOPE_IDENTITY().Я был в состоянии создать хранимую процедуру:. SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ПО GO ALTER PROCEDURE [DBO] [раскручивает] (@N VARCHAR (30) КАК BEGIN TRANSACTION Ins вставить в (п) ЗНАЧЕНИЯ (@N) ВЫБОР NewID = SCOPE_IDENTITY() – Keith
«с помощью В.Б. Я назвал SP:
Установить сп = Server.CreateObject ("ADODB.Connection") CONNECTSTRING = "DSN" cn.Open CONNECTSTRING, "user", "PW0rd" Установить rs = Server.CreateObject ("ADODB.Recordset") set rs = cn.Execute ("EXEC [DB]. [dbo]. [A] @ Str =" & str)
'вернуть значение:
resultID = rs (0) – Keith