SQL Server存储过程中的自定义标识符生成

Bil*_*lla 4 sql sql-server stored-procedures sql-server-2008

目前正在处理多租户应用程序,在存储过程中生成标识符时存在问题.

我有一个这个表有一个关于租户的元信息.

承租人

TenantId
Name
IDPrefix,   -->Like SFT
IDStart     --> 000001
Run Code Online (Sandbox Code Playgroud)

客户

TenantID
ClientIdentfier --> Like SFT000001
Run Code Online (Sandbox Code Playgroud)

在存储过程中我想生成下一个ClientIdentifierSFT000002.

我怎么能根据最后一个ClientIdentifier值+1 来做?

我知道只用以下代码取最后一个值.

select max(ClientID) + 1 from Client will give 1,2,etc
Run Code Online (Sandbox Code Playgroud)

但我想我做不到

 DECLARE @CIdentier Varchar(50);

 select @CIdentier = select max(ClientIdentifier) + 1 from Client 
                                            to produce 'SFT000002
Run Code Online (Sandbox Code Playgroud)

我怎么能在存储过程中这样做?

编辑:

尝试过mark_s回答,它就像一个魅力!

mar*_*c_s 5

这种方法在加载时是安全的,例如它不会返回任何重复项,即使很多客户端请求同时进入(这是从@remusrusanu的答案"借用"到SO上的另一个问题).

基本上,你需要用列的顺序表TenantID,TenantPrefix并且CurrentValue然后就可以使用这样的存储过程,以获取安全的新的价值:

-- add a IDValue column to your Tenant table
ALTER TABLE dbo.Tenant
ADD IDValue INT NOT NULL DEFAULT(0)

-- create this procedure to fetch the next value for any given tenant
CREATE PROCEDURE dbo.GetNextTenantID
   @tenantID INT,    
   @NextID VARCHAR(15) OUTPUT
AS
   SET NOCOUNT ON;

   DECLARE @Out TABLE (NextVal INT, Prefix CHAR(3))

   UPDATE dbo.Tenant
   SET IDValue = IDValue + 1
   OUTPUT INSERTED.IDValue, INSERTED.IDPrefix INTO @Out(NextVal, prefix)

   SELECT TOP 1 @nextID = Prefix + CAST(NextVal AS VARCHAR(10)) FROM @Out
GO
Run Code Online (Sandbox Code Playgroud)

这里的要点是:你必须IDValue单个 UPDATE语句中增加和返回它.只有这种方法,你可以在负载下的安全-所有这些具有的途径SELECT第一,增量,然后UPDATE不是安全的,可以返回重复.

更新:不能只将这段代码包含在您的更大程序中!离开这个过程因为是和只是把它从你的存储过程-是这样的:

ALTER PROCEDURE [dbo].[AddClient]  
(
   @TenantId INT,
   @FirstName NVARCHAR(100),
   @LastName NVARCHAR(100),
   @ContactPerson NVARCHAR(100)
)
AS 
BEGIN 
     SET NOCOUNT ON   

     IF @TenantId IS NULL 
        RAISERROR('The value for @TenantID should not be null', 15, 1) -- with log

     DECLARE @new_person_id INT
     DECLARE @new_patient_id INT
     DECLARE @ClientIdentifier NVARCHAR(50)

     -- call the stored procedure to get the next ClientIdentifier here
     EXEC dbo.GetNextTenantID @TenantID, @ClientIdentifier OUTPUT

     -- then go on and do your other lines of code from here on out .....
     ......
END
Run Code Online (Sandbox Code Playgroud)

  • @ user1909604:没有你不能 - 函数无法修改数据库 (2认同)