Jyr*_*kka 2 database-design sql-server dml t-sql
是否可以有一个基于 Identity 列的具有 PK 的表?
假设我有一个客户表,两个字段对于我们的案例很重要,Id
即 isPK
nvarchar(20)
和SequenceId
which is 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
Run Code Online (Sandbox Code Playgroud)
你从来没有设置过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)
)
Run Code Online (Sandbox Code Playgroud)
如果需要,您应该能够CustomerID
在上表中设置主键。由于该Sequence
值已经是唯一的(由于是 IDENTITY),我会质疑为什么要创建复合主键。你确定这是你想要的设计吗?