Identity列に基づくPKを持つテーブルを作成することは可能ですか?
私が顧客のテーブルを持っているとしましょう。私たちのケースでは2つのフィールドが重要ですId
はPK
nvarchar(20)
であり、SequenceId
はint
identity(1,1)
。 (特に)パラメータ@CustomerType
を含むストアドプロシージャが必要です。このパラメータに基づいて、Id
の値を生成し、新しい行をテーブルに挿入します。このようなもの:
CREATE PROCEDURE createCustomer
@CustomerType int,
@GivenName nvarchar(20),
@Surname nvarchar(20),
@BirthDate date = null
...
AS
BEGIN
SET NOCOUNT ON;
DECLARE @prefix nvarchar(1) = N'x'
IF @CustomerType = 1
BEGIN
SET @prefix = N'P'
END
...
ELSE
BEGIN
SET @prefix = N'x'
END
INSERT INTO [dbo].[Customers]
([Id],
[GivenName],[Surname],[BirthDate])
VALUES
(@prefix + (SequenceId + 1000000),
@GivenName,@Surname,@BirthDate);
SELECT INSERTED.Id AS CustomerId;
END
値を取得する場所を指定していないので、SequenceIDは無効です。一時変数をもう1つ作成して、以下のようなものを追加することをお勧めします
@seqid intを宣言する
--seqidの@seqid = next値を選択シーケンスから
その後、シーケンスの代わりに、この変数を保持します
SequenceId
に何も設定しないでください。同じ挿入操作で設定される同じテーブルのIDENTITY列の値を参照する式を使用して、挿入中に列の値を設定することはできません。考えてみれば、挿入するまで行は存在しないため、挿入の開始時にIDENTITY値がないため、これは理にかなっています。
プレフィックスとIDENTITY値を連結する列を作成する場合は、計算列を使用する必要があります。次に例を示します。
CREATE TABLE dbo.Customers
( Sequence int IDENTITY(1,1) NOT NULL
, Prefix nchar(1) NOT NULL
, CustomerID AS Prefix + CAST(Sequence + 1000000 as nvarchar(8))
, GivenName nvarchar(50)
... etc ...
, CONSTRAINT UN_CustomersSequence UNIQUE (Sequence)
, CONSTRAINT PK_Customers PRIMARY KEY (CustomerID)
)
必要に応じて、上の表のCustomerID
を主キーにできるはずです。 Sequence
の値は既に一意であるため(IDENTITYであるため)、複合主キーを作成する理由を質問します。これがあなたが望むデザインでよろしいですか?
コードで値を計算するのではなく、計算列を検討してください。
ALTER TABLE dbo.Customers
DROP COLUMN Id;
ALTER TABLE dbo.Customers
ADD Id AS (CASE CustomerType WHEN 1 THEN N'P' ELSE N'x' END + CAST((SequenceId + 1000000) AS nvarchar(10)));
以下は、この計算された列を使用した挿入プロシージャの例です。
CREATE PROCEDURE createCustomer
@CustomerType int
, @GivenName nvarchar(20)
, @Surname nvarchar(20)
, @BirthDate date = NULL
AS
SET NOCOUNT ON;
INSERT INTO [dbo].[Customers]
( [GivenName]
, [Surname]
, [BirthDate]
)
OUTPUT inserted.Id
VALUES ( @GivenName
, @Surname
, @BirthDate
);
GO
編集:列の永続化に関するコメントを削除しました。
identity
フィールドは、代理キーフィールドであることを意図しています。 PKであるという事実は、一意性を保証するものであり、必ずしもアイデンティティ自体を保証するものではありません。サロゲートキーの値を割り当てる意味はありません。つまり、テーブルに挿入されたときのシーケンスでさえ、関連する行については何も想定できません。つまり、ID 1000がID 1001の前にテーブルに挿入されたと想定しないでください。
@Joel Brownによって提案されたprefix
フィールドなどの他のフィールドには、追加の意味を配置する必要があります。管理reallyがプレフィックスとIDの値を結合したい場合は、レポートで確認してください。設計に組み込まないでください。あなたは将来のために大きな頭痛の種で設計します。
また、identity
フィールドを定義して、すべてのクエリに追加するのではなく、1000000から開始することもできます。