代码之家  ›  专栏  ›  技术社区  ›  Cyberherbalist

为什么用SELECT@@IDENTITY调用T-SQL INSERT会插入重复项?

  •  0
  • Cyberherbalist  · 技术社区  · 2 年前

    我本可以发誓我以前做过这种事情,而不会创建重复的行,但也许有些事情发生了变化,或者我只是在做一些奇怪的事情?

    无论如何,我有一个表,它的定义如下:

    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运行SProc,只会发生一次插入,并且会按预期返回新的标识密钥。但是,当我在应用程序中运行以下代码时,会插入两个重复的行!当然有不同的身份密钥,返回的身份是第二个。

    affectedCount = command.ExecuteNonQuery();
    
    if (affectedCount > 0) 
    { 
        succeeded = true;
        newID = (int)command.ExecuteScalar();
    }
    

    但是,如果我不执行命令。在C#代码中执行Scalar()以获取@@IDENTITY。没有创建重复项!

    发生了什么事?

    编辑添加:发生的事情是,我忘记了如何获得@@IDENTITY(或SCOPE_IDENTITY),现在我觉得我在这里发布这条消息很愚蠢。请随意投票结束这个问题。我很不好意思发布它,但如果我没有发布,我可能需要几天的时间才能弄清楚问题出在哪里。我不认为我开始患老年痴呆症,但这总是有可能的!

    1 回复  |  直到 2 年前
        1
  •  7
  •   Marc Gravell    2 年前

    你执行了两次-一次通过 ExecuteNonQuery 一次通过 ExecuteScalar 。不要那样做!只需使用 ExecuteScalar (因为它返回一行一列)。如果您明确需要rowcount, ExecuteReader 提供通过 RecordsAffected -或选择 @@rowcount 作为第二列(但您仍然不能使用 ExecuteScalar ,因为:2列)