Korzystam z Dappera, aby wykonać następujące zapytanie przeciwko wystąpieniu programu SQL Server 2008 R2 Express z aplikacji 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
Wezwanie connection.Query<int>(sql, ...)
to zgłasza wyjątek dotyczący nieprawidłowej obsady. Debugowałem go i jest to punkt, w którym Dapper wzywa GetValue
zwracany SqlDataReader
.
Zwracanym typem GetValue
jest to Object
, że sprawdzanie go w programie debuggera jest dziesiętne.
Jeśli zmienię opcję select na SELECT CAST(@@IDENTITY as int)
, zwracana wartość GetValue jest zapakowana w int i wyjątek nie jest zgłaszany.
Kolumna Id jest zdecydowanie typu int; Po co SELECT @@IDENTITY
zwracać dziesiętne?
Niektóre dodatkowe informacje:
- Baza danych jest nowa.
- Tabela klientów jest jedynym obiektem, który do niej dodałem. W bazie danych nie ma innych tabel (widoków), wyzwalaczy ani procedur przechowywanych (użytkowników).
- Baza danych zawiera 10 wierszy, tam Id to 1,2,3,4,5,6,7,8,9,10 (tj. Kolumna nie przekracza wartości int).
Moja definicja tabeli to
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.
źródło
źródło
Odpowiedzi:
@@ tożsamość zwraca wartość liczbową (38,0) . Musisz rzucić go, aby dostać się do int.
WYBIERZ CAST (@@ tożsamość AS INT)
Spróbuj też zamiast tego użyć scope_identity. Jeśli masz jakieś wyzwalacze w tabeli Klientów, możesz w końcu uzyskać ostatnią tożsamość z innej tabeli.
Wreszcie, ponieważ używasz eleganckiego , będziesz chciał zawinąć to wszystko w procedurę składowaną, aby zagwarantować wykonanie wstawienia, a następnie zaznaczenia tożsamości w tej samej partii.
Teoretycznie większość czasu powinno działać samodzielnie. Ale mogą pojawić się problemy, jeśli musisz dwukrotnie przejść do bazy danych. (Np. Jak to działa z pulą połączeń? A co z porzuconymi połączeniami? Itd.) Jeśli po prostu rzucisz to wszystko w procedurę składowaną, nie będziesz musiał się martwić o dodatkowy wysiłek na drodze.
źródło
Utwórz tabelę mówi:
„ TOŻSAMOŚĆ
Wskazuje, że nowa kolumna jest kolumną tożsamości. Po dodaniu nowego wiersza do tabeli Microsoft SQL Server ™ zapewnia unikalną, przyrostową wartość dla kolumny. Kolumny tożsamości są powszechnie używane w połączeniu z ograniczeniami PIERWOTNEGO KLUCZA, aby służyć jako unikalny identyfikator wiersza dla tabeli. Właściwość TOŻSAMOŚĆ można przypisać do kolumn tinyint, smallint, int, bigint, dziesiętnych (p, 0) lub liczbowych (p, 0). Dla jednej tabeli można utworzyć tylko jedną kolumnę tożsamości. Domyślne ograniczenia i ograniczenia DOMYŚLNE nie mogą być używane z kolumną tożsamości. Musisz podać zarówno ziarno, jak i przyrost, albo żadne. Jeśli nie podano żadnego z nich, wartością domyślną jest (1,1).
nasionko
Jest wartością używaną dla pierwszego wiersza załadowanego do tabeli.
przyrost
Czy załadowano wartość przyrostową dodaną do wartości tożsamości poprzedniego wiersza. ”
Tak więc funkcja systemowa @@ tożsamość będzie musiała poradzić sobie z najbardziej zakrywającym typem.
źródło
numeric
ponieważ ma najszerszy zasięg ..? Dzięki„Dlaczego SELECT @@ TOŻSAMOŚĆ zwraca dziesiętne”
Ponieważ może być zbyt duży, aby zmieścił się w
int
- nie pasuje do typu kolumny tożsamości, ale jak mówi Richard zwraca liczbę (38,0) (numeric
idecimal
są synonimami )źródło