web-dev-qa-db-ja.com

`SELECT @@ IDENTITY`が小数を返すのはなぜですか?

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が返されたGetValueSqlDataReaderを呼び出す時点です。

GetValue の戻り値の型はObjectであり、デバッガーショーで検査すると、ボックス化された10進数です。

SelectをSELECT CAST(@@IDENTITY as int)に変更すると、GetValueの戻り値はボックス化された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]
_
24
Greg B
  1. @@ identityは数値(38,0) を返します。 intにするには、キャストする必要があります。

    SELECT CAST(@@ identity AS INT)

  2. また、代わりにscope_identityを使用してみてください。 Customersテーブルにトリガーがある場合、別のテーブルから最後のIDを取得する可能性があります。

  3. 最後に、 dapper を使用しているので、すべてをストアドプロシージャ内にラップして、同じバッチでIDの挿入と選択の実行が保証されるようにします。

    理論的には、ほとんどの場合、両方を単独で実行することで機能します。ただし、データベースに2回アクセスする必要がある場合は、問題が発生する可能性があります。 (たとえば、これは接続プーリングでどのように機能しますか?ドロップされた接続はどうですか?など)ストアドプロシージャですべてをスローするだけであれば、将来の余分な労力について心配する必要はありません。

28
Richard

テーブルの作成 は言う:

"[〜#〜] identity [〜#〜]

新しい列がID列であることを示します。新しい行がテーブルに追加されると、Microsoft®SQL Server™は列に一意の増分値を提供します。 ID列は通常、PRIMARY KEY制約と組み合わせて使用​​され、テーブルの一意の行識別子として機能します。 IDENTITYプロパティは、tinyint、smallint、int、bigint、decimal(p、0)、またはnumeric(p、0)列に割り当てることができます。のみテーブルごとに1つのID列を作成できます。バインドされたデフォルトとDEFAULT制約は、ID列では使用できません。シードと増分の両方を指定するか、どちらも指定しないでください。どちらも指定されていない場合、デフォルトは(1,1)です。

シード

テーブルにロードされる最初の行に使用される値です。

増分

ロードされた前の行のID値に追加された増分値ですか?」

したがって、システム関数@@ identityは、最もカバーするタイプに対応する必要があります。

10
Marian

「SELECT @@ IDENTITYが10進数を返す理由」

大きすぎてintに収まらない可能性があるため、ID列のタイプとは一致しませんが、Richardが言うように、numeric(38,0)(numericおよびdecimal同義語です