このアプローチは、負荷がかかった状態で安全です。たとえば、多数のクライアントリクエストが同時に着信した場合でも、重複は返されません(これは、@ 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
ここでの主なポイントは、単一のステートメント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