2009-02-26 2 views
9

Как я могу вернуть автогенерированный ID для новой записи, которую я только что вставил? (Использование ASP классический и MSSQL 2005)получить новый идентификатор записи SQL

+0

спасибо всем, кто предложил 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

+0

«с помощью В.Б. Я назвал 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

ответ

0

Спасибо всем, кто предложил 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.

25
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; 
9

SELECT @@ IDENTITY обычно работает, но может вернуть идентификатор записи, вставленной из триггера или что-то, а не оригинал.

SELECT SCOPE_IDENTITY - это то, что я рекомендую. Он возвращает значения, вставленные только в пределах текущей области.

Существует также IDENT_CURRENT (имя_таблицы) ", который возвращает последний идентификатор, вставленный для конкретной таблицы.

3

SELECT @@ Identity или SELECT SCOPE_IDENTITY() оба работают, однако выбор SCOPE_Identity() безопаснее, поскольку он возвращает последний автоматически сгенерированный идентификатор в пределах текущей области. Например, предположим, что у нас есть таблица под названием ScopeIDTable, и в этой таблице есть триггер. Этот триггер будет вставляться в запись в TriggerIdTable, обе таблицы имеют столбец автоматического увеличения.

Если вы используете SELECT @@ Identity, вы получите последний автоинкремент в этом сеансе, который будет идентификатором, сгенерированным с помощью триггера (TriggerIdTable).

Если вы используете SELECT SCOPE_IDENTITY(), вы получите идентификатор из своего ScopeIdTable.

9

Есть три способа, чтобы получить последнее тождество в 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 это слишком далеко, чтобы показать примеры первых двух из клиентского кода ,

1

Вы запускаете запрос

select scope_identity() 

с использованием того же соединения с базой данных, прежде чем делать что-нибудь еще с ним. В результате, как вы, вероятно, ожидаете, набор записей, содержащий одну строку, которая имеет одно поле. Вы можете получить доступ к полю, используя индекс 0, или вы можете дать ему имя, если вы предпочитаете:

select scope_identity() as lastId 
0

Где нужно вставить сразу в моде на основе набора несколько записей, он может получить более интересным.

Иногда я использовал GUID, созданный клиентами (но для классического ASP вам, вероятно, потребуется использовать служебную программу для генерации значений) или, чаще всего, ограничение NEWSQUENTIALID() в столбце ключа GUID на сервере.

Я знаю не всех, как GIUDS, хотя по некоторым вполне обоснованным причинам (их размер и то, как он влияет на индексирование/пейджинг для одного).

http://www.sqlmag.com/Articles/Index.cfm?ArticleID=50164&pg=2

1

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

@@identity 

так

select scope_identity() 

, очевидно, является самым экономить способ сделать то, что шотландец просит.