违反约束并行运行

问题描述:

我创建了一个将作为主键为我的表违反约束并行运行

CREATE FUNCTION dbo.NewCustomerPK() 
RETURNS VARCHAR (10) 
AS 
BEGIN 
DECLARE @LastCustID VARCHAR(10) 
DECLARE @newID  INT 
DECLARE @charID  CHAR(10) 


SELECT 
    @LastCustID = MAX(CustID) 
FROM 
    dbo.TestCust 

IF (@LastCustID IS NULL) 
BEGIN 
    SET @LastCustID = 'CUST000001' 
END 
ELSE 
BEGIN 

    SET @newID = RIGHT(@LastCustID, 6) + 1 
    SET @charID = 'CUST' + RIGHT(('0000000' + CONVERT(VARCHAR(6), @newID)), 6) 
    SET @LastCustID = @charID 

END 

RETURN @LastCustID 

END 

CREATE TABLE dbo.TestCust 
(
    CustID VARCHAR(10) PRIMARY KEY NOT NULL DEFAULT dbo.NewCustomerPK(), 
    Name  VARCHAR(50) 
) 

功能并试图插入测试数据

DECLARE @Counter INT = 1, 
     @Stopper INT = 500000 

WHILE(@Counter <= @Stopper) 
BEGIN 

INSERT INTO dbo.TestCust(NAME) 
VALUES('test'+CONVERT(VARCHAR(6), @Counter)) 

SET @Counter = @Counter + 1 
END 

它工作正常,但是当我尝试并行运行(在新窗口中运行循环数据插入)会导致主约束违例错误

+0

使其成为触发。 – Jester 2015-02-10 07:41:11

另一种方法是将标识列与计算列组合使用。

create table dbo.TestCust 
(
    ID int identity not null, 
    CustID as isnull('CUST'+right('0000000' + convert(varchar(6), ID), 6), ''), 
    Name varchar(50), 
    constraint PK_TestCust_CustID primary key clustered (CustID) 
); 

周围的CustID计算的isnull在那里,以确保柱将永远不会有NULL值,这使得它可以使用CustID作为主键。

不知道是否有可能修复您当前的设计。也许在添加新行时使用隔离级别可串行化可以做到这一点。

CREATE TRIGGER tr_Group ON TargetTable 
INSTEAD OF INSERT 
AS 
BEGIN 
SET NOCOUNT ON 
    INSERT INTO dbo.targetTable 
    SELECT dbo.NewCustomerPK(),<other fields> 
    FROM INSERTED 
END