Neden SELECT @@ IDENTITY `bir ondalık döndürüyor?


24

Bir ASP.NET MVC 3 (.NET 4.0) uygulamasından bir SQL Server 2008 R2 Express örneğine karşı aşağıdaki sorguyu çalıştırmak için Dapper kullanıyorum .

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

SELECT @@IDENTITY

Çağrısı connection.Query<int>(sql, ...)Geçersiz Oyuncular İstisnası atıyor. Hata ayıkladım ve Dapper'ın GetValuegeri döndüğü yerde SqlDataReader.

Dönüş tipi GetValueDİR Objectayıklayıcı gösterisinde İncelemeden, bir kutulu ondalık bu.

Seçimi olarak değiştirirsem, SELECT CAST(@@IDENTITY as int)GetValue öğesinin geri dönüşü kutulu bir int olur ve istisna atılmaz.

Id sütunu kesinlikle int türündedir; Neden SELECT @@IDENTITYbir ondalık verir?

Bazı ek bilgiler:

  • Veri tabanı yepyeni.
  • Müşteriler tablosu, ona eklediğim tek nesne. Veritabanında başka (kullanıcı) tablo, görünüm, tetikleyici veya saklı yordam yok.
  • Veritabanında 10 satır var, Id var 1,2,3,4,5,6,7,8,9,10 (yani sütun bir int sınırının dışında değil).

Tablo tanımım

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]

Müşteriler tablosunda herhangi bir tetikleyici var mı?
Richard,

3
Ben kullanırsınız ) SCOPE_IDENTITY ( yerine @@ KİMLİK. @@ KİMLİK, mevcut kapsamınızdaki aksine, mevcut bağlantıda herhangi bir şey tarafından oluşturulan son kimlik değerini verecektir. Bu nedenle, Richard'ın önerdiği gibi, başka bir tabloyu değiştiren ve bir kimlik oluşturan bir tetikleyici @@ IDENTITY'nin geri dönüşünü etkileyecektir.
Nick Chammas,

Veritabanında tetikleyici yok. Bu yeni bir veritabanı ve Müşteriler masası oluşturduğum tek masa.
Greg B

@Greg B: bu, fonksiyonun geri dönüş tipidir. İnt türünden bigint'i geri dönüş türü olarak mı bekliyorsunuz (soruya göre) veya bu işlev için MS seçimini mi sorguluyorsunuz?
Marian,

Yanıtlar:


28
  1. @@ Kimlik sayısal bir sayı döndürür (38,0) . Bir int elde etmek için yayın yapmanız gerekecek.

    SELECT CAST (@@ INT kimliği)

  2. Ayrıca, bunun yerine kapsam_adını kullanmayı deneyin. Müşteriler tablosunda herhangi bir tetikleyiciniz varsa, en son kimliği başka bir tablodan alabilirsiniz.

  3. Son olarak, kepçeyi kullandığınız için , tüm ekleri , aynı serideki kimliğin seçildiğinden emin olmanız için saklı bir prosedürün içine sarmak isteyeceksiniz.

    Teorik olarak, her ikisini de kendi başlarına yürütmek için çoğu zaman çalışmalıdır. Ancak veritabanına iki kez gitmek zorunda kalırsanız sorunlar ortaya çıkabilir. (Örneğin, bağlantı havuzlaması ile nasıl çalışır? Bağlantılar ne durumda? Vb.) Bunları saklı bir prosedürde attığınızda, bu ilave çaba için endişelenmenize gerek kalmayacaktır.


# 3 için teşekkürler. Geçici bir SQL deyiminde bir toplu iş tanımlamanın bir yolu yok mu?
Greg B

Ona bir kez daha bakıyordum. Tüm ifadeleri tek bir çağrıya eklerseniz, hepsi bir toplu işlemdir. İfadeleri ayrı aramalara bölerseniz, işler karışabilir.
Richard,

3
SCOPE_IDENTITY () öneren için +1 ()
Andrew Bickerton

10

Tablo oluştur diyor:

" KİMLİK

Yeni sütunun bir kimlik sütunu olduğunu gösterir. Tabloya yeni bir satır eklendiğinde, Microsoft® SQL Server ™, sütun için benzersiz, artan bir değer sağlar. Kimlik sütunları genellikle tablo için benzersiz bir satır tanımlayıcısı olarak hizmet etmek için PRIMARY KEY kısıtlamaları ile birlikte kullanılır. IDENTITY özelliği, tinyint, smallint, int, bigint, ondalık (p, 0) veya sayısal (p, 0) sütunlara atanabilir. Tablo başına sadece bir kimlik sütunu oluşturulabilir. Bağlı varsayılanlar ve DEFAULT kısıtlamaları bir kimlik sütunu ile kullanılamaz. Hem tohum hem de artış ya da ikisini belirtmelisiniz. Hiçbiri belirtilmezse, varsayılan değer (1,1).

tohum

Tabloya yüklenen ilk satır için kullanılan değerdir.

artım

Artımlı değer, yüklenen önceki satırın kimlik değerine eklenir mi? "

Bu nedenle @@ kimliği sistem fonksiyonu en çok örtücü tiple başa çıkmak zorunda kalacak.


Ve bu yüzden numericen geniş menzile sahip olduğu için geri döner ..? Teşekkürler
Greg B

3
Bir işlev birden fazla dönüş türüne sahip olamaz. Her olasılığı dahil etmek için en geniş tipini kullanmak zorunda kalacak.
Marian,

6

"SELECT @@ IDENTITY neden bir ondalık döndürür"

Bir içine sığmayacak kadar büyük olabileceğinden int- kimlik sütununun türüyle eşleşmiyor ancak Richard'ın dediği gibi sayısal bir sayı (38,0) ( numericve decimal eşanlamlıdır )

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.