创建CRUD程序,复制遗留程序,根据“下一个ID”生成唯一ID。字段在一个单独的表中。我没有复制使用单独的表,而是编写了一个存储过程来读取表中的行数。
CREATE PROCEDURE [TLA_CreateItem]
@SiteReference varchar(50)
,@ItemID varchar(4)
,@NewUniqueID varchar(68) OUTPUT
AS
BEGIN
DECLARE @Rows varchar(12)
SET @Rows = (CONVERT(varchar(12), (SELECT Count(UniqueID) FROM [TLA_Items]) + 1))
SET @NewUniqueID = @ItemID + @SiteReference + @Rows
INSERT INTO [TLA_Items] ([ItemID], [UniqueID])
VALUES (@ItemID, @NewUniqueID)
SELECT @NewUniqueID
END
我已经简化了上面的代码,但未显示的是TLA_Items
表还有一个IDENTITY
列,并且它需要与SQL Server 2008一起使用。< / p>
UniqueID字段必须与旧版程序的模式匹配:ItemID + SiteReference + (integer representing number of previous records)
然而,在测试这个时,我发现了我的逻辑缺陷。如果删除行,则可以创建与现有行匹配的唯一ID。这在遗留系统中不会发生,因为很少删除行,而单独的表存储序列中的下一个数字。
除了将下一个ID值存储在单独的表中之外,是否有更好的技术来创建与传统模式匹配的唯一ID?
答案 0 :(得分:2)
您可以让您的过程仅将前缀(@ItemID + @SiteReference
)存储到UniqueID
中,并使用FOR INSERT触发器将IDENTITY值作为行组件追加到插入行,如下所示:
CREATE TRIGGER TLA_Items_Adjust
ON dbo.TLA_Items
FOR INSERT
AS
BEGIN
UPDATE t
SET t.UniqueID = i.UniqueID + CAST(t.IdentityColumn AS varchar(10))
FROM dbo.TLA_Items AS t
INNER JOIN inserted AS i
ON t.IdentityColumn = i.IdentityColumn
;
END
要读取并返回新生成的UniqueID
值作为OUTPUT参数以及行,您可以在INSERT语句中使用表变量和OUTPUT子句,如下所示:
CREATE PROCEDURE [TLA_CreateItem]
@SiteReference varchar(50)
,@ItemID varchar(4)
,@NewUniqueID varchar(68) OUTPUT
AS
BEGIN
DECLARE @GeneratedUniqueID TABLE (UniqueID varchar(68));
INSERT INTO dbo.[TLA_Items] ([ItemID], [UniqueID])
OUTPUT inserted.UniqueID INTO @GeneratedUniqueID (UniqueID)
VALUES (@ItemID, @ItemID + @SiteReference);
SELECT @NewUniqueID = UniqueID FROM @GeneratedUniqueID;
SELECT @NewUniqueID;
END
虽然不是使用OUTPUT,但您可能只是从与SCOPE_IDENTITY()结果匹配的行中读取值:
CREATE PROCEDURE [TLA_CreateItem]
@SiteReference varchar(50)
,@ItemID varchar(4)
,@NewUniqueID varchar(68) OUTPUT
AS
BEGIN
INSERT INTO dbo.[TLA_Items] ([ItemID], [UniqueID])
VALUES (@ItemID, @ItemID + @SiteReference);
SELECT @NewUniqueID = UniqueID
FROM dbo.TLA_Items
WHERE IdentityColumn = SCOPE_IDENTITY();
SELECT @NewUniqueID;
END
答案 1 :(得分:2)
以下是另一种选择,但请注意会影响现有的UniqueID
值。
如果您可以对表架构进行轻微更改,则可以添加一个名为UniqueIDPrefix
的列:
ALTER TABLE dbo.TLA_Items
ADD UniqueIDPrefix varchar(56) NOT NULL;
并将UniqueID
列重新定义为计算列:
ALTER TABLE dbo.TLA_Items
DROP COLUMN UniqueID;
GO
ALTER TABLE dbo.TLA_Items
ADD UniqueID AS UniqueIDPrefix + CAST(IdentiyColumn AS varchar(12));
在您的存储过程中,您需要填充UniqueIDPrefix
而不是UniqueID
(只有@ItemID + @SiteReference
的结果)
INSERT INTO dbo.[TLA_Items] ([ItemID], [UniqueIDPrefix])
VALUES (@ItemID, @ItemID + @SiteReference);
并使用OUTPUT或SCOPE_IDENTITY()读取UniqueID
的值,如my other answer中所示。
答案 2 :(得分:0)
这听起来像是在使用SQL 2008,但是如果你在2012年,你可以使用一个序列来存储递增值。
从不删除怎么样?您可以在表中添加一个标志以进行逻辑删除。