왜 SELECT @@ IDENTITY가 10 진수를 반환합니까?


24

Dapper 를 사용하여 ASP.NET MVC 3 (.NET 4.0) 응용 프로그램의 SQL Server 2008 R2 Express 인스턴스에 대해 다음 쿼리를 실행하고 있습니다.

INSERT INTO Customers (
         Type, Name, Address, ContactName, 
         ContactNumber, ContactEmail, Supplier)
VALUES (
         @Type, @Name, @Address, @ContactName, 
         @ContactNumber, @ContactEmail, @Supplier)

SELECT @@IDENTITY

에 대한 호출에서 connection.Query<int>(sql, ...)잘못된 캐스트 예외가 발생했습니다. 나는 그것을 디버깅했고 그것이 Dapper가 GetValue리턴 된 지점에 SqlDataReader있습니다.

의 반환 형식 GetValueIS Object디버거 쇼에서 검사는, 그것은 박스 소수의입니다.

select를으로 변경하면 SELECT CAST(@@IDENTITY as int)GetValue의 반환은 boxed int이며 예외는 발생하지 않습니다.

Id 열은 확실히 int 유형입니다. SELECT @@IDENTITY소수를 반환합니까?

몇 가지 추가 정보 :

  • 데이터베이스는 아주 새롭습니다.
  • Customers 테이블은 내가 추가 한 유일한 개체입니다. 데이터베이스에는 다른 (사용자) 테이블, 뷰, 트리거 또는 저장 프로 시저가 없습니다.
  • 데이터베이스에 10 개의 행이 있고 ID가 1,2,3,4,5,6,7,8,9,10입니다 (즉, 열이 int의 한계를 초과하지 않음).

내 테이블 정의는

CREATE TABLE [dbo].[Customers](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Type] [int] NOT NULL,
    [Name] [nvarchar](255) NOT NULL,
    [Address] [nvarchar](1000) NOT NULL,
    [ContactName] [nvarchar](255) NOT NULL,
    [ContactNumber] [nvarchar](50) NOT NULL,
    [ContactEmail] [nvarchar](255) NOT NULL,
    [Supplier] [nvarchar](255) NOT NULL,
 CONSTRAINT [PK_Customers] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (
    PAD_INDEX  = OFF, 
    STATISTICS_NORECOMPUTE  = OFF, 
    IGNORE_DUP_KEY = OFF, 
    ALLOW_ROW_LOCKS  = ON, 
    ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

고객 테이블에 트리거가 있습니까?
Richard

3
내가 사용하는 것이 ) SCOPE_IDENTITY을 ( 대신 @@ IDENTITY. @@ IDENTITY는 현재 범위와 달리 현재 연결에서 생성 된 마지막 ID 값을 제공합니다. 따라서 Richard가 제안한 것처럼 다른 테이블을 수정하고 ID를 생성하는 트리거는 @@ IDENTITY의 리턴에 영향을줍니다.
Nick Chammas

DB에는 트리거가 없습니다. 새로운 데이터베이스이며 Customers 테이블은 내가 만든 유일한 테이블입니다.
Greg B

@Greg B : 함수의 반환 유형입니다. 반환 유형으로 int / bigint를 기대 했습니까 (질문에서 알 수 있듯이)이 기능에 대한 MS 선택에 의문을 제기하고 있습니까?
Marian

답변:


28
  1. @@ identity는 numeric (38,0)을 반환합니다 . int로 가져 오려면 캐스팅해야합니다.

    방송 선택 (@@ identity AS INT)

  2. 또한 scope_identity를 대신 사용해보십시오. Customers 테이블에 트리거가 있으면 다른 테이블에서 마지막 ID를 얻을 수 있습니다.

  3. 마지막으로 dapper를 사용 하고 있기 때문에 저장 프로 시저 안에 모든 것을 래핑하여 삽입을 실행 한 다음 동일한 배치에서 ID를 선택해야합니다.

    이론적으로는 두 가지를 모두 자체적으로 실행하는 것이 대부분의 시간 동안 작동해야합니다. 그러나 데이터베이스로 두 번 이동해야하는 경우 문제가 발생할 수 있습니다. (예를 들어, 연결 풀링에서 어떻게 작동합니까? 연결 끊김은 어떻게됩니까?


# 3 감사합니다. 임시 SQL 문 에서 배치를 정의 할 수있는 방법이 없습니까?
Greg B

나는 그것을 다시보고 있었다. 한 번의 호출에 모든 명령문을 포함 시키면 모두 한 번의 일괄 처리입니다. 명령문을 별도의 호출로 나누면 문제가 발생할 수 있습니다.
Richard

3
SCOPE_IDENTITY () 추천 +1
앤드류 비 커튼

10

테이블 만들기 는 다음과 같이 말합니다.

" 정체성

새 열이 ID 열임을 나타냅니다. 새 행이 테이블에 추가되면 Microsoft® SQL Server ™는 열에 고유 한 증분 값을 제공합니다. ID 열은 일반적으로 PRIMARY KEY 제약 조건과 함께 사용되어 테이블의 고유 한 행 식별자로 사용됩니다. IDENTITY 속성은 tinyint, smallint, int, bigint, decimal (p, 0) 또는 numeric (p, 0) 열에 할당 할 수 있습니다. 테이블 당 하나의 ID 열만 만들 수 있습니다. 바운드 기본값 및 DEFAULT 제약 조건은 ID 열과 함께 사용할 수 없습니다. 시드와 증분을 모두 지정하거나 둘 다 지정하지 않아야합니다. 어느 것도 지정하지 않으면 기본값은 (1,1)입니다.

테이블에로드 된 첫 번째 행에 사용 된 값입니다.

증가

로드 된 이전 행의 ID 값에 증분 값이 추가 되었습니까? "

따라서 @@ identity 시스템 기능은 가장 많은 유형을 처리해야합니다.


그리고 이것이 numeric가장 넓은 범위를 가지 면서 돌아 오는 이유입니다 ..? 감사합니다
Greg B

3
함수는 둘 이상의 리턴 유형을 가질 수 없습니다. 모든 가능성을 포함하려면 가장 넓은 유형을 사용해야합니다.
Marian

6

"SELECT @@ IDENTITY가 10 진수를 반환하는 이유"

그것이에 맞게 너무 클 수 있기 때문에 int- 그것은 식별 컬럼의 유형과 일치하지 않습니다하지만 리처드는 반환에게 숫자 (38,0)을 말하는 것처럼 ( numericdecimal 동의어이다 )

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.