Saya menggunakan Dapper untuk menjalankan kueri berikut terhadap contoh SQL Server 2008 R2 Express dari aplikasi ASP.NET MVC 3 (.NET 4.0).
INSERT INTO Customers (
Type, Name, Address, ContactName,
ContactNumber, ContactEmail, Supplier)
VALUES (
@Type, @Name, @Address, @ContactName,
@ContactNumber, @ContactEmail, @Supplier)
SELECT @@IDENTITY
Panggilan untuk connection.Query<int>(sql, ...)
melempar Pengecualian Pemain Tidak Valid. Saya sudah men-debug dan itu pada titik di mana Dapper memanggil GetValue
yang dikembalikan SqlDataReader
.
Jenis kembalinya GetValue
adalah Object
, memeriksanya di acara debugger itu adalah desimal kotak.
Jika saya mengubah pilih ke SELECT CAST(@@IDENTITY as int)
, kembalinya GetValue adalah kotak int dan pengecualian tidak dibuang.
Kolom Id jelas bertipe int; Mengapa SELECT @@IDENTITY
mengembalikan desimal?
Beberapa informasi tambahan:
- Basis datanya baru.
- Tabel Pelanggan adalah satu-satunya objek yang saya tambahkan ke dalamnya. Tidak ada tabel (pengguna) lain, pandangan, pemicu atau prosedur tersimpan dalam database.
- Ada 10 baris dalam database, ada Id 1,2,3,4,5,6,7,8,9,10 (yaitu kolom tidak di luar batas int).
Definisi tabel saya adalah
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]
sql-server
t-sql
ado.net
Greg B
sumber
sumber
Jawaban:
@@ identitas mengembalikan angka (38,0) . Anda harus membuangnya untuk mencapai int.
SELECT CAST (@@ identity AS INT)
Selain itu, coba gunakan scope_identity sebagai gantinya. Jika Anda memiliki pemicu pada tabel Pelanggan, Anda mungkin mendapatkan identitas terakhir dari tabel lain.
Akhirnya, karena Anda menggunakan necis , Anda harus membungkus semua itu di dalam prosedur tersimpan sehingga Anda dijamin untuk mengeksekusi memasukkan dan kemudian pilih pada identitas dalam batch yang sama.
Secara teoritis, itu harus bekerja sebagian besar waktu untuk mengeksekusi keduanya sendiri. Tetapi masalah bisa muncul jika Anda harus pergi ke database dua kali. (Misalnya bagaimana ini bekerja dengan koneksi pooling? Bagaimana dengan koneksi yang terputus? Dll.) Jika Anda hanya membuang semuanya dalam prosedur tersimpan, Anda tidak perlu khawatir tentang upaya ekstra di jalan.
sumber
Buat tabel mengatakan:
" IDENTITAS
Menunjukkan bahwa kolom baru adalah kolom identitas. Ketika baris baru ditambahkan ke tabel, Microsoft® SQL Server ™ memberikan nilai tambahan yang unik untuk kolom. Kolom identitas umumnya digunakan bersama dengan batasan PRIMARY KEY untuk berfungsi sebagai pengidentifikasi baris unik untuk tabel. Properti IDENTITY dapat ditetapkan ke kolom tinyint, smallint, int, bigint, desimal (p, 0), atau numerik (p, 0). Hanya satu kolom identitas yang dapat dibuat per tabel. Default batas dan batasan DEFAULT tidak dapat digunakan dengan kolom identitas. Anda harus menentukan seed dan increment atau keduanya. Jika tidak ada yang ditentukan, standarnya adalah (1,1).
benih
Apakah nilai yang digunakan untuk baris pertama dimuat ke dalam tabel.
kenaikan
Apakah nilai tambahan ditambahkan ke nilai identitas dari baris sebelumnya yang dimuat. "
Jadi fungsi sistem @@ identitas harus mengatasi jenis yang paling mencakup.
sumber
numeric
karena memiliki jangkauan terluas ..? Terima kasih"Mengapa SELECT @@ IDENTITY mengembalikan desimal"
Karena mungkin terlalu besar untuk dimasukkan dalam
int
- itu tidak cocok dengan jenis kolom identitas tetapi seperti kata Richard mengembalikan numerik (38,0) (numeric
dandecimal
sinonim )sumber