2014-10-09 60 views
2

假设你有以下结构的表:T-SQL的唯一标识列作为复合主键的一部分

CREATE TABLE [log] (
    [type] int NOT NULL, 
    [stat] nvarchar(20) NOT NULL, 
    [id] int IDENTITY (1, 1) NOT NULL, 
    descr nvarchar(20), 
    PRIMARY KEY ([type], [stat], [id]) 
) 

是否有可能迫使[id]要递增仅每当其他两个PK场具有相同的值,而不是像现在这样独立?例如:

type stat  id  descr 
5  ERROR  1  Test <--- 
3  WARNING 1  Test 
5  ERROR  2  Test <--- 
2  ERROR  1  Test 
1  WARNING 1  Test 
5  WARNING 1  Test 
5  ERROR  3  Test <--- 
+0

在一个字的回答解决这个问题:没有 – Paparazzi 2014-10-09 11:22:53

+0

使用触发增量 http://stackoverflow.com/questions/3583973/using-a-trigger-to-simulate-a-second-identity-column-in-sql-server-2005 – Recursive 2014-10-09 11:25:07

回答

3

否。IDENTITY(或SEQUENCE)的用途仅用于生成增量整数。由于值不会被重用,因此可能存在差距,并且可能保留值但不使用。

您可以在查询中使用表达式来显示所需的值。

ROW_NUMBER() OVER (PARTITION BY type, stat ORDER BY id) AS Seq 
0

这不是3NF
我将与数据设计

CREATE TABLE [logBase] (
    [id] int IDENTITY (1, 1) NOT NULL, 
    PRIMARY KEY ([id]) 
) 

CREATE TABLE [status] (
    [id] int IDENTITY (1, 1) NOT NULL, 
    descr nvarchar(20), 
    PRIMARY KEY ([id]) 
) 

CREATE TABLE [log] (
    [type] int NOT NULL, 
    [statusID] nvarchar(20) NOT NULL, 
    [baseID] int NOT null, 
    descr nvarchar(20), 
    PRIMARY KEY ([type], [statusID], [baseID]) 
) 
+1

所述密钥有三列,并且示例数据证实唯一的其他可能密钥将全部为4;假设descr可以是任何东西,这3个形式是唯一的关键,表格是5nf。此外,所述的约束是转换约束并且不排除任何特定的表值。重新设计:在日志中缺少baseId;引入statusID与正常化无关;你缺少FK从日志状态ID到状态ID,我想日志baseId为logBase ID;目前还不清楚为什么logBase&baseID。 – philipxy 2014-10-11 04:58:44

+0

@philipxy PRIMARY KEY([type],[statusID],[baseID]) – Paparazzi 2014-10-11 12:24:23

+1

@Blam,你说什么原始设计是“不是3NF”?就3NF而言,似乎没有什么明显的错误。 – sqlvogel 2014-10-12 08:32:19

1

这个我想会得到你的工作完成

CREATE TABLE [LOG1] (
    [TYPE] INT NOT NULL, 
    [STAT] NVARCHAR(20) NOT NULL, 
    [ID] INT , 
    DESCR NVARCHAR(20), 
    PRIMARY KEY ([TYPE], [STAT], [ID]) 
) 

CREATE TRIGGER TR_LOG 
ON [DBO].[LOG1] 
INSTEAD OF INSERT 
AS 
BEGIN 
DECLARE @CNT INT=0 
IF EXISTS(SELECT 'X' FROM LOG1 A JOIN INSERTED B ON A.TYPE=B.TYPE AND A.STAT=B.STAT) 
SET @CNT=(SELECT COUNT(*) FROM LOG1 A JOIN INSERTED B ON A.TYPE=B.TYPE AND A.STAT=B.STAT) 
PRINT @CNT 
INSERT INTO LOG1(TYPE,STAT,ID,DESCR) 
SELECT TYPE,STAT,[email protected],DESCR FROM INSERTED 
END