我正在寻找一种解决方案,以便基于另一个字段在我的表上添加一个版本列。
就像我的桌子上没有外地文件一样。每次插入具有相同文档的新行时,我都不想增加列的版本。
我知道我可以在后端完成。但是,这意味着我必须先阅读表然后插入。我的想法是优化性能并将其留给SQL Server。
有可能吗?
pk DocNo Version
---------------------
1 ABC 0
2 CBD 0
3 ABC 1
4 FGH 0
5 ABC 2
假设您可以参数化查询(如在存储过程中一样),并且主键设置为IDENTITY
,则可以使用以下方式:
INSERT INTO TableA (DocNo, Version)
(SELECT TOP 1 'XYZ',ISNULL(MAX(Version)+1,0)
FROM TableA WHERE DocNo = 'XYZ')
我使用了'XYZ'
,您将在其中放置参数,例如:
INSERT INTO TableA (DocNo, Version)
(SELECT TOP 1 @DocNo,ISNULL(MAX(Version)+1,0)
FROM TableA WHERE DocNo = @DocNo)
存储过程解决方案
CREATE PROCEDURE tableUpsert(@DocNo varchar(100))
AS
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRAN
IF EXISTS(SELECT * FROM dbo.YourTable WITH (UPDLOCK) WHERE DocNo = @DocNo)
UPDATE dbo.YourTable
SET Version = Version + 1
WHERE DocNo = @DocNo;
ELSE
INSERT dbo.YourTable(DocNo, Version)
VALUES(@DocNo, 1);
COMMIT
代码非常不言自明。如果记录存在,则通过增加VersionNumber列进行更新,如果不存在,则插入默认VersionNumber为1的新记录。请注意,使用UPDLOCK可以确保仅特定进程当前正在更新记录。