我可以发誓我以前做过这种事情,但没有创建重复的行,但也许有些东西已经改变了,或者我只是做了一些奇怪的事情?
无论如何,我有一个具有以下定义的表格:
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]
添加新语音时,我使用这个存储过程:
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
如果我从 SSMS 运行 SPproc,则只会发生一次插入,并且会按预期返回新的身份密钥。但是当我在应用程序中运行以下代码时,会插入两个重复的行!当然使用不同的身份密钥,返回的身份是第二个。
affectedCount = command.ExecuteNonQuery();
if (affectedCount > 0)
{
succeeded = true;
newID = (int)command.ExecuteScalar();
}
但是,如果我不执行 C# 代码中的 command.ExecuteScalar() 来获取 @@IDENTITY,则不会创建重复项!
发生什么事了?
您执行了两次 - 一次通过
ExecuteNonQuery
,一次通过 ExecuteScalar
。不要那样做!只需使用 ExecuteScalar
(因为它返回一行和一列)。如果您明确需要行数,则 ExecuteReader
通过 RecordsAffected
提供 - 或选择 @@rowcount
作为第二列(但您仍然不能使用 ExecuteScalar
,因为:2 列)