문제

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

나는 ~에 대해 알고 있다 @@IDENTITY 그리고 IDENT_CURRENT 그리고 SCOPE_IDENTITY 그러나 각각에 첨부된 장단점을 이해하지 못합니다.

차이점과 각각을 언제 사용해야 하는지 설명해 주실 수 있나요?

도움이 되었습니까?

해결책

  • @@IDENTITY 모든 범위에 걸쳐 현재 세션의 테이블에 대해 생성된 마지막 ID 값을 반환합니다. 여기서 조심해야 해요, 범위에 걸쳐 있기 때문입니다.현재 명령문 대신 트리거에서 값을 얻을 수 있습니다.

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

  • IDENT_CURRENT('tableName') 모든 세션 및 범위의 특정 테이블에 대해 생성된 마지막 ID 값을 반환합니다.이를 통해 위의 두 테이블이 필요한 테이블이 아닌 경우에 어떤 테이블에서 값을 가져올지 지정할 수 있습니다(매우 드물다).또한 @와 같이가이 스타벅 "레코드를 삽입하지 않은 테이블의 현재 IDENTITY 값을 얻으려는 경우 이 방법을 사용할 수 있습니다."

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

다른 팁

삽입된 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() 이 문제를 해결합니다.마지막 항목의 ID를 반환합니다. 당신이 삽입했습니다 SQL 코드에서 너가 보냈다 데이터베이스에.트리거가 추가 행을 생성하는 경우 잘못된 값이 반환되지 않습니다.만세

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);

insert sql 문 끝에

NewId = command.ExecuteScalar()

그것을 되찾을 것이다.

MSDN

@@IDENTITY, SCOPE_IDENTITY 및 IDENT_CURRENT는 테이블의 IDENTITY 열에 삽입된 마지막 값을 반환한다는 점에서 유사한 함수입니다.

@@IDENTITY 및 SCOPE_IDENTITY는 현재 세션의 테이블에서 생성된 마지막 ID 값을 반환합니다.그러나 SCOPE_IDENTITY는 현재 범위 내의 값만 반환합니다.@@IDENTITY는 특정 범위로 제한되지 않습니다.

IDENT_CURRENT는 범위와 세션에 의해 제한되지 않습니다.지정된 테이블로 제한됩니다.IDENT_CURRENT는 모든 세션 및 범위의 특정 테이블에 대해 생성된 ID 값을 반환합니다.자세한 내용은 IDENT_CURRENT를 참조하세요.

  • IDENT_CURRENT 테이블을 인수로 취하는 함수입니다.
  • @@신원 테이블에 트리거가 있으면 혼란스러운 결과가 반환될 수 있습니다.
  • SCOPE_IDENTITY 대부분의 경우 당신의 영웅입니다.

Entity Framework를 사용하면 내부적으로 OUTPUT 새로 삽입된 ID 값을 반환하는 기술

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

출력 결과는 임시 테이블 변수에 저장되고, 테이블에 다시 조인되며, 테이블에서 행 값을 반환합니다.

메모:EF가 임시 테이블을 다시 실제 테이블에 내부 조인하는 이유를 모르겠습니다(어떤 상황에서 두 테이블이 일치하지 않는지).

하지만 그것이 EF가 하는 일입니다.

이 기술(OUTPUT)은 SQL Server 2008 이상에서만 사용할 수 있습니다.

@@신원 현재 SQL 연결을 사용하여 삽입된 마지막 ID입니다.이는 새 레코드에 삽입된 ID만 필요하고 나중에 더 많은 행이 추가되었는지 상관하지 않는 삽입 저장 프로시저에서 반환하기에 좋은 값입니다.

SCOPE_IDENTITY 현재 SQL 연결을 사용하여 삽입된 마지막 ID이며 현재 범위에서 즉, 삽입 후 트리거를 기반으로 두 번째 IDENTITY가 삽입된 경우 SCOPE_IDENTITY에는 반영되지 않고 수행한 삽입만 반영됩니다.솔직히 말해서 이것을 사용할 이유가 없었습니다.

IDENT_CURRENT(테이블 이름) 연결이나 범위에 관계없이 삽입된 마지막 ID입니다.레코드를 삽입하지 않은 테이블의 현재 IDENTITY 값을 얻으려는 경우 이를 사용할 수 있습니다.

다른 버전의 SQL Server에서는 말할 수 없지만 2012에서는 직접 출력이 잘 작동합니다.임시 테이블을 사용하여 귀찮게 할 필요가 없습니다.

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

그런데 이 기술은 여러 행을 삽입할 때도 작동합니다.

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

산출

ID
2
3
4

언제나 scope_identity()를 사용하면 다른 것은 전혀 필요하지 않습니다.

삽입문 뒤에 이것을 추가해야 합니다.그리고 데이터가 삽입되는 테이블 이름을 확인하십시오. 삽입 문에 의해 지금 막 영향을 받은 행이 없는 현재 행을 얻게 됩니다.

IDENT_CURRENT('tableName')

마지막으로 추가/업데이트된 ID를 찾고 계신다면 조금 구식일 수도 있지만 더 정확하게는 이전 PHP 5.5 이전 버전을 사용하는 사람들이 많습니다.자세한 내용은 다음에서 확인할 수 있습니다. http://php.net/manual/en/function.mysql-insert-id.php

$last = mysql_insert_id();

만들기 uuid 열에도 삽입합니다.그러면 uuid로 행을 쉽게 식별할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top