your programing

삽입 된 행의 ID를 얻는 가장 좋은 방법은 무엇입니까?

lovepro 2020. 9. 27. 13:35
반응형

삽입 된 행의 ID를 얻는 가장 좋은 방법은 무엇입니까?


IDENTITY삽입 된 행 을 얻는 가장 좋은 방법은 무엇입니까 ?

내가 알고 @@IDENTITY하고 IDENT_CURRENT하고 SCOPE_IDENTITY있지만 각에 부착 된 장점과 단점을 이해하지 않습니다.

누군가가 차이점과 언제 각각을 사용 해야하는지 설명해 주시겠습니까?


  • @@IDENTITY모든 범위에서 현재 세션의 테이블에 대해 생성 된 마지막 ID 값을 반환합니다. 범위에 관계없이 여기 에서 주의해야합니다 . 현재 명령문 대신 트리거에서 값을 가져올 수 있습니다.

  • SCOPE_IDENTITY()현재 세션 및 현재 범위의 테이블에 대해 생성 된 마지막 ID 값을 반환합니다. 일반적으로 사용하려는 것 .

  • IDENT_CURRENT('tableName')세션 및 범위의 특정 테이블에 대해 생성 된 마지막 ID 값을 반환합니다. 이렇게하면 위의 두 가지가 필요한 것이 아닌 경우 ( 매우 드문 경우 ) 값을 원하는 테이블을 지정할 수 있습니다 . 또한 @ Guy Starbuck이 언급했듯이 "레코드를 삽입하지 않은 테이블에 대한 현재 IDENTITY 값을 얻으려면 이것을 사용할 수 있습니다."

  • 명령문 OUTPUTINSERT통해 해당 명령문을 통해 삽입 된 모든 행에 액세스 할 수 있습니다. 특정 문으로 범위가 지정 되었기 때문에 위의 다른 함수보다 더 간단 합니다. 그러나 좀 더 장황하고 (테이블 변수 / 임시 테이블에 삽입 한 다음 쿼리해야 함) 문이 롤백되는 오류 시나리오에서도 결과를 제공합니다. 즉, 쿼리가 병렬 실행 계획을 사용하는 경우 이것이 ID를 얻기위한 유일한 보장 된 방법 입니다 (병렬 처리를 해제하지 않는 경우). 그러나 트리거 전에 실행되며 트리거 생성 값을 반환하는 데 사용할 수 없습니다.


삽입 된 ID를 검색하는 가장 안전하고 정확한 방법은 출력 절을 사용하는 것입니다.

예를 들어 (다음 MSDN 문서 에서 가져옴 )

USE AdventureWorks2008R2;
GO
DECLARE @MyTableVar table( NewScrapReasonID smallint,
                           Name varchar(50),
                           ModifiedDate datetime);
INSERT Production.ScrapReason
    OUTPUT INSERTED.ScrapReasonID, INSERTED.Name, INSERTED.ModifiedDate
        INTO @MyTableVar
VALUES (N'Operator error', GETDATE());

--Display the result set of the table variable.
SELECT NewScrapReasonID, Name, ModifiedDate FROM @MyTableVar;
--Display the result set of the table.
SELECT ScrapReasonID, Name, ModifiedDate 
FROM Production.ScrapReason;
GO

다른 사람들과 똑같은 말을했기 때문에 모두가 맞습니다. 좀 더 명확하게하려고합니다.

@@IDENTITY클라이언트가 데이터베이스에 연결하여 삽입 된 마지막 항목의 ID를 반환합니다.
대부분의 경우 제대로 작동하지만 때로는 트리거가 가서 모르는 새 행을 삽입하고 원하는 행 대신이 새 행에서 ID를 가져옵니다.

SCOPE_IDENTITY()이 문제를 해결합니다. 데이터베이스에 보낸 SQL 코드에 삽입 한 마지막 항목의 ID를 반환 합니다. 트리거가 추가 행을 생성하면 잘못된 값이 반환되지 않습니다. 만세

IDENT_CURRENT모든 사람이 삽입 한 마지막 ID를 반환합니다. 다른 앱이 예기치 않은 시간에 다른 행을 삽입하는 경우 해당 행 대신 해당 행의 ID를 받게됩니다.

안전하게 플레이하려면 항상 SCOPE_IDENTITY(). 계속 @@IDENTITY해서 누군가가 나중에 트리거를 추가하기로 결정하면 모든 코드가 손상됩니다.


새로 삽입 된 행의 ID를 얻는 가장 좋은 (읽기 : 가장 안전한) 방법은 다음 output을 사용하는 것입니다 .

create table TableWithIdentity
           ( IdentityColumnName int identity(1, 1) not null primary key,
             ... )

-- type of this table's column must match the type of the
-- identity column of the table you'll be inserting into
declare @IdentityOutput table ( ID int )

insert TableWithIdentity
     ( ... )
output inserted.IdentityColumnName into @IdentityOutput
values
     ( ... )

select @IdentityValue = (select ID from @IdentityOutput)

더하다

SELECT CAST(scope_identity() AS int);

삽입 SQL 문 끝까지

NewId = command.ExecuteScalar()

그것을 검색합니다.


When you use Entity Framework, it internally uses the OUTPUT technique to return the newly inserted ID value

DECLARE @generated_keys table([Id] uniqueidentifier)

INSERT INTO TurboEncabulators(StatorSlots)
OUTPUT inserted.TurboEncabulatorID INTO @generated_keys
VALUES('Malleable logarithmic casing');

SELECT t.[TurboEncabulatorID ]
FROM @generated_keys AS g 
   JOIN dbo.TurboEncabulators AS t 
   ON g.Id = t.TurboEncabulatorID 
WHERE @@ROWCOUNT > 0

The output results are stored in a temporary table variable, joined back to the table, and return the row value out of the table.

Note: I have no idea why EF would inner join the ephemeral table back to the real table (under what circumstances would the two not match).

But that's what EF does.

This technique (OUTPUT) is only available on SQL Server 2008 or newer.


MSDN

@@IDENTITY, SCOPE_IDENTITY, and IDENT_CURRENT are similar functions in that they return the last value inserted into the IDENTITY column of a table.

@@IDENTITY and SCOPE_IDENTITY will return the last identity value generated in any table in the current session. However, SCOPE_IDENTITY returns the value only within the current scope; @@IDENTITY is not limited to a specific scope.

IDENT_CURRENT is not limited by scope and session; it is limited to a specified table. IDENT_CURRENT returns the identity value generated for a specific table in any session and any scope. For more information, see IDENT_CURRENT.

  • IDENT_CURRENT is a function which takes a table as a argument.
  • @@IDENTITY may return confusing result when you have an trigger on the table
  • SCOPE_IDENTITY is your hero most of the time.

@@IDENTITY is the last identity inserted using the current SQL Connection. This is a good value to return from an insert stored procedure, where you just need the identity inserted for your new record, and don't care if more rows were added afterward.

SCOPE_IDENTITY is the last identity inserted using the current SQL Connection, and in the current scope -- that is, if there was a second IDENTITY inserted based on a trigger after your insert, it would not be reflected in SCOPE_IDENTITY, only the insert you performed. Frankly, I have never had a reason to use this.

IDENT_CURRENT(tablename) is the last identity inserted regardless of connection or scope. You could use this if you want to get the current IDENTITY value for a table that you have not inserted a record into.


I can't speak to other versions of SQL Server, but in 2012, outputting directly works just fine. You don't need to bother with a temporary table.

INSERT INTO MyTable
OUTPUT INSERTED.ID
VALUES (...)

By the way, this technique also works when inserting multiple rows.

INSERT INTO MyTable
OUTPUT INSERTED.ID
VALUES
    (...),
    (...),
    (...)

Output

ID
2
3
4

ALWAYS use scope_identity(), there's NEVER a need for anything else.


Create a uuid and also insert it to a column. Then you can easily identify your row with the uuid. Thats the only 100% working solution you can implement. All the other solutions are too complicated or are not working in same edge cases.


After Your Insert Statement you need to add this. And Make sure about the table name where data is inserting.You will get current row no where row affected just now by your insert statement.

IDENT_CURRENT('tableName')

If you are looking for the last ID added/updated, this may be a little old-school, but there are a lot of people using older PHP, Pre 5.5 to be more precise. More details can be found at http://php.net/manual/en/function.mysql-insert-id.php

$last = mysql_insert_id();

참고URL : https://stackoverflow.com/questions/42648/best-way-to-get-identity-of-inserted-row

반응형