I have a table with the following definition:
CREATE TABLE [dbo].[speech](
[id] [int] IDENTITY(1,1) NOT NULL,
[speaker] [int] NOT NULL,
[speech_date] [date] NOT NULL,
[subject] [varchar](250) NULL,
CONSTRAINT [PK_speech] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
When adding a new speech, I am using this stored procedure:
CREATE PROCEDURE [dbo].[add_speech]
@speaker int
, @speak_date date
, @subject varchar(250)
AS
BEGIN
INSERT INTO [dbo].[speech]
([speaker]
,[speech_date]
,[subject])
VALUES
(@speaker
,@speak_date
,@subject);
SELECT CAST(@@IDENTITY AS int);
END
If I run the SProc from SSMS only one insert occurs, and the new Identity key is returned as expected. But when I run the following code in my application, two duplicate rows are inserted! With different identity keys, of course, and the identity returned is the second one.
affectedCount = command.ExecuteNonQuery();
if (affectedCount > 0)
{
succeeded = true;
newID = (int)command.ExecuteScalar();
}
But, if I don't execute the command.ExecuteScalar()
in the C# code to get the @@IDENTITY
, a duplicate is not created!
What is going on?
You executed it twice - once via ExecuteNonQuery
and once via ExecuteScalar
. Don't do that! Just use ExecuteScalar
(since it returns one row and one column). If you explicitly need the rowcount, ExecuteReader
provides that via RecordsAffected
- or select @@rowcount
as a second column (but then you still can't use ExecuteScalar
, because: 2 columns)