【问题标题】:Primary Key Error while inserting record into table将记录插入表时出现主键错误
【发布时间】:2014-11-28 19:57:06
【问题描述】:

我将数据表作为输入参数传递给存储过程。我已经为它创建了自定义类型。

这是我的存储过程:

CREATE PROCEDURE [dbo].[Proc_AddEmployee]
      @tblEmp EmpType READONLY,
      @Code int
AS
BEGIN    
      INSERT INTO Employee ([Name], [Lname], [Code])
         SELECT 
             [Name], [Lname], @Code 
         FROM @tblEmp

这里它从数据表中获取记录并插入到Employee表中。

Employee 具有主键(NameLname 的组合)。

Employee:

Nmae   LName Code
Rashmi Hirve 89
Rani   Mohite 7

数据表:

Nmae   LName
Rani   Mohite
Swati  More
Reshma Gawade

当我尝试将记录 (Rani, Mohite) 从数据表添加到表 Employee 时出现问题。

它在第一个记录时导致主键错误,并且不会继续进行。

如果出现错误,我想要这样,跳过该记录获取下一条记录并插入该记录。有 8000 条记录,我想将它们从数据表传递到 Employee 表。

如果我勾选不存在,那么insert执行查询需要很长时间。如何处理?

【问题讨论】:

    标签: sql asp.net sql-server


    【解决方案1】:

    INSERT 语句中添加对EXISTS 的检查不会对性能产生显着影响。

    INSERT INTO Employee ([Name] ,[Lname] ,[Code])
    SELECT  [Name] ,[Lname] ,@Code 
    FROM    @tblEmp AS t
    WHERE   NOT EXISTS
            (   SELECT  1
                FROM    Employee AS e
                WHERE   e.Name = t.Name
                AND     e.Lname = t.Lname
            );
    

    这是相当安全的,但仍然容易受到race condition 的攻击。我认为最安全的插入方法是使用MERGE 和锁定提示HOLDLOCK

    MERGE Employee WITH(HOLDLOCK) AS t
    USING @tbl AS s
        ON s.Name = t.Name
        AND s.LName = t.LName
    WHEN NOT MATCHED THEN 
        INSERT ([Name] ,[Lname] ,[Code])
        VALUES (s.Name, s.Lname, @Code);
    

    【讨论】:

    • 它起作用了。但我不明白你为什么写 1。你能解释一下代码吗?从员工中选择 1 作为 e.Name = t.Name AND
    • 我认为documentation on EXISTS 可能比我解释得更好,但本质上它确保您只选择@tblEmp 中不存在于Employee 中的行。 SELECT 1 只是我的偏好,你可以使用SELECT NULL,或者SELECT *,或者SELECT Name,真的没关系,优化掉了。我只是认为SELECT 1SELECT NULL 更好地表明没有选择任何相关内容的意图,而SELECT 1 是两者中较短的一个。
    【解决方案2】:

    如果表有一个未设置为自动生成的主键,那么当您尝试插入没有该键的记录时它将出错。您需要将主键字段设置为身份种子,或者您可以在插入时包含主键。

    【讨论】:

      猜你喜欢
      • 2016-10-18
      • 2019-09-15
      • 2021-03-31
      • 2022-01-20
      • 1970-01-01
      • 2016-12-26
      • 2016-11-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多