将记录插入表时出现主键错误

时间:2014-11-28 11:51:28

标签: sql asp.net sql-server

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

这是我的存储过程:

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

DataTable:

Nmae   LName
Rani   Mohite
Swati  More
Reshma Gawade

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

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

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

如果我检查不存在,那么插入将花费很长时间来执行查询。如何处理?

2 个答案:

答案 0 :(得分:1)

EXISTS语句中添加对INSERT的检查不应对性能产生重大影响。

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 :(得分:0)

如果表的主键未设置为自动生成,则在尝试插入没有键的记录时会出错。您需要将主键字段设置为标识种子,或者可以将主键包含在插入中。