[sql] SQL Server-INSERT 후 반환 값

INSERT 문 후에 키-값을 다시 얻으려고합니다. 예 : 속성 이름과 ID가있는 테이블이 있습니다. id는 생성 된 값입니다.

    INSERT INTO table (name) VALUES('bob');

이제 동일한 단계에서 ID를 다시 얻고 싶습니다. 이것은 어떻게 이루어 집니까?

우리는 Microsoft SQL Server 2008을 사용하고 있습니다.



답변

별도의 SELECT가 필요하지 않습니다 …

INSERT INTO table (name)
OUTPUT Inserted.ID
VALUES('bob');

이것은 비 IDENTITY 열 (예 : GUID)에서도 작동합니다.


답변

SCOPE_IDENTITY()새로운 ID 값을 얻는 데 사용

INSERT INTO table (name) VALUES('bob');

SELECT SCOPE_IDENTITY()

http://msdn.microsoft.com/en-us/library/ms190315.aspx


답변

INSERT INTO files (title) VALUES ('whatever');
SELECT * FROM files WHERE id = SCOPE_IDENTITY();

트리거가있는 테이블에서 OUTPUT 절 충돌과 관련하여 알려진 문제가 있으므로 가장 안전한 방법입니다. 테이블에 현재 트리거가없는 경우에도이를 신뢰할 수 없게 만듭니다. 누군가 줄을 추가하면 애플리케이션이 중단됩니다. 시한 폭탄 종류의 행동.

자세한 설명은 msdn 기사를 참조하십시오.

http://blogs.msdn.com/b/sqlprogrammability/archive/2008/07/11/update-with-output-clause-triggers-and-sqlmoreresults.aspx


답변

Entity Framework는 gbn의 답변과 비슷한 것을 수행합니다.

DECLARE @generated_keys table([Id] uniqueidentifier)

INSERT INTO Customers(FirstName)
OUTPUT inserted.CustomerID INTO @generated_keys
VALUES('bob');

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

출력 결과는 임시 테이블 변수에 저장된 후 클라이언트로 다시 선택됩니다. 문제를 알고 있어야합니다.

삽입은 둘 이상의 행을 생성 할 수 있으므로 변수가 둘 이상의 행을 보유 할 수 있으므로 둘 이상을 리턴 할 수 있습니다 ID

EF가 임시 테이블을 내부 테이블과 다시 결합하는 이유를 알 수 없습니다 (어떤 상황에서 두 가지가 일치하지 않을까요).

그러나 이것이 EF가하는 일입니다.

SQL Server 2008 이상 만 2005 년이면 운이 나쁘다.


답변

@@IDENTITY 마지막으로 삽입 된 ID 값을 반환하는 시스템 함수입니다.


답변

삽입 후 종료하는 방법에는 여러 가지가 있습니다

테이블에 데이터를 삽입 할 때 OUTPUT 절을 사용하여 테이블에 삽입 된 데이터의 복사본을 반환 할 수 있습니다. OUTPUT 절은 두 가지 기본 형식 인 OUTPUT 및 OUTPUT INTO를 사용합니다. 데이터를 호출 응용 프로그램으로 리턴하려면 OUTPUT 양식을 사용하십시오. 데이터를 테이블 또는 테이블 변수로 리턴하려면 OUTPUT INTO 양식을 사용하십시오.

DECLARE @MyTableVar TABLE (id INT,NAME NVARCHAR(50));

INSERT INTO tableName
(
  NAME,....
)OUTPUT INSERTED.id,INSERTED.Name INTO @MyTableVar
VALUES
(
   'test',...
)

IDENT_CURRENT : 세션에서 특정 테이블 또는 뷰에 대해 생성 된 마지막 ID를 반환합니다.

SELECT IDENT_CURRENT('tableName') AS [IDENT_CURRENT]

SCOPE_IDENTITY : 같은 세션과 같은 범위에서 마지막 아이디를 반환합니다. 범위는 저장 프로 시저 / 트리거 등입니다.

SELECT SCOPE_IDENTITY() AS [SCOPE_IDENTITY];  

@@ IDENTITY : 동일한 세션에서 마지막 ID를 반환합니다.

SELECT @@IDENTITY AS [@@IDENTITY];


답변

가장 확실한 솔루션은 SCOPE_IDENTITY() 입니다.

동일한 범위에서 두 개의 삽입을 호출 할 수 있으므로 모든 삽입 후 범위 ID를 가져와 변수에 저장해야합니다.

ident_current그리고 @@identity그들이 일을하지만 그들이 안전 범위 아니다. 큰 응용 프로그램에서 문제가 발생할 수 있습니다

  declare @duplicataId int
  select @duplicataId =   (SELECT SCOPE_IDENTITY())

자세한 내용은 여기에 Microsoft 문서