2015-02-10 66 views
2

我創建了一個將作爲主鍵爲我的表違反約束並行運行

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

回答

3

另一種方法是將標識列與計算列組合使用。

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作爲主鍵。

不知道是否有可能修復您當前的設計。也許在添加新行時使用隔離級別可串行化可以做到這一點。

-2
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