Mar*_*c D 4 sql sql-server identity primary-key
在我的SQL Server 2012数据库中,我正在创建“任务”表,该表将具有由三个字段组成的复合主键:
Issue_ID [int] NOT NULL,
Issue_Sub_ID [int] NOT NULL,
Task_ID [int] NOT NULL
Run Code Online (Sandbox Code Playgroud)
Issue_ID并且Issue_Sub_ID是其他表的外键。在我创建的表中,每个Issue_ID/ Issue_Sub_ID组合可能有许多任务。
我想做的是为该Task_ID列建立一个默认值,这与我使用过的值类似IDENTITY(1,1),但是它将基于Issue_ID/ Issue_Sub_ID组自动增加。例如,Task_ID给定提供的Issue_ID/ Issue_Sub_ID值,结果将如下所示:
Issue_ID Issue_Sub_ID Task_ID
======== ============ =======
12345 1 1
12345 1 2
12345 1 3
12345 2 1
12345 2 2
67890 2 1
67890 2 2
67890 2 3
Run Code Online (Sandbox Code Playgroud)
我熟悉ROW_NUMBER() OVER(PARTITION BY Issue_ID, Issue_Sub_ID ORDER BY Issue_ID, Issue_Sub_ID)可能的解决方案,但是,由于我希望此列成为表的复合主键的一部分,所以我认为这行不通。
提前谢谢大家。
我同意Sean的观点-添加一个identity列,然后仅使用一个计算列作为任务ID。尽管我已经回答的问题非常喜欢这一个在这里,我不知道这个标记作为一个重复。这样做的原因是您要将用task_id作主键的一部分。
但是,我不确定这是否可行,因为为了在主键中包含计算列,它必须是persisted,并且由于某种原因(我认为是因为使用了UDF),SQL Server不允许我标记坚持不懈。
无论如何,这是我为此建议的解决方案:
首先,创建一个将计算任务ID的函数:
CREATE FUNCTION dbo.GenerateTaskId
(
@Row_Id int,
@Issue_Id int,
@Issue_Sub_Id int
)
RETURNS Int
AS
BEGIN
RETURN
(
SELECT COUNT(*)
FROM dbo.Tasks
WHERE Issue_Id = @Issue_Id
AND Issue_Sub_ID = @Issue_Sub_ID
AND Row_Id <= @Row_Id
)
END
GO
Run Code Online (Sandbox Code Playgroud)
然后,使用任务ID作为计算列创建表:
CREATE TABLE dbo.Tasks
(
Row_Id [int] IDENTITY(1,1),
Issue_ID [int] NOT NULL,
Issue_Sub_ID [int] NOT NULL,
Task_Id AS dbo.GenerateTaskId(Row_Id, Issue_Id, Issue_Sub_Id),
CONSTRAINT PK_Tasks PRIMARY KEY (Row_Id)
)
GO
Run Code Online (Sandbox Code Playgroud)
现在,对其进行测试:
INSERT INTO Tasks VALUES
(12345, 1),
(12345, 1),
(12345, 1),
(12345, 2),
(12345, 2),
(67890, 2),
(67890, 2),
(67890, 2)
SELECT *
FROM Tasks
Run Code Online (Sandbox Code Playgroud)
结果:
Row_Id Issue_ID Issue_Sub_ID Task_Id
1 12345 1 1
2 12345 1 2
3 12345 1 3
4 12345 2 1
5 12345 2 2
6 67890 2 1
7 67890 2 2
8 67890 2 3
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
717 次 |
| 最近记录: |