违反约束并行运行
问题描述:
我创建了一个将作为主键为我的表违反约束并行运行
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
它工作正常,但是当我尝试并行运行(在新窗口中运行循环数据插入)会导致主约束违例错误
答
另一种方法是将标识列与计算列组合使用。
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
使其成为触发。 – Jester 2015-02-10 07:41:11