主键由外键和标识组成,应在条件下重置标识

时间:2012-12-29 11:04:44

标签: sql sql-server sql-server-2008

create table Linq_TB
{
   url_id int NOTNULL,
   Pg_Name nvarchar(50) NOTNULL,
   URL nvarchar(50) NUTNULL,

   CONSTRAINT Linq_id PRIMARY KEY (url_id,DBCC Checkident(Linq_TB,RESEED,0) case url_id not in(select URL_Id from URL_TB ))
}

我想创建一个表格,其主键是Linq_id,并从url_id和身份获取它的值,从1开始,1加1 。url_id是外键。例如,如果url_id为1,linq_id将为11,12,13,......我还希望在{{1}时重置linq_id身份变化。

查询应该是什么?上面的查询不起作用,为什么?

提前致谢

2 个答案:

答案 0 :(得分:0)

好吧,约束包含条件而不是要执行的代码。您应该考虑为您的任务使用存储过程,也可以考虑使用自行开发的分配ID的方法。

然而,将主键“漂亮”或格式化并不常见,因为没有真正的好处(可能除了可能用于调试目的)。

我建议不要在url_ID发生变化时执行DBCC。这对绩效产生了很大的负面影响。

为什么不把ID保留下来?

答案 1 :(得分:0)

您可以使用下表和触发器定义执行此操作:

CREATE TABLE Linq_TB
(
   url_id INT NOT NULL,
   Linq_id INT NOT NULL,
   Pg_Name NVARCHAR(50) NOT NULL,
   URL NVARCHAR(50) NOT NULL,

   CONSTRAINT PK_Link_TB PRIMARY KEY (url_id, Linq_id),
   CONSTRAINT FK_URL_TB_URL_ID FOREIGN KEY (url_id) REFERENCES URL_TB (url_id)
)
GO

CREATE TRIGGER tr_Linq_TB_InsertUpdate
ON Linq_TB
INSTEAD OF INSERT
AS
    INSERT INTO Linq_TB
    SELECT i.url_id,
        ISNULL(tb.Linq_id, 0)
            + row_number() over (partition by i.url_id order by (select 1)),
        i.Pg_Name, i.URL
    FROM inserted i
    LEFT OUTER JOIN 
            (
            SELECT url_id, MAX(Linq_ID) Linq_id
            FROM Linq_TB
            GROUP BY url_id
            ) tb ON i.url_id = tb.url_id
GO

CREATE TABLE定义了您的列和约束。并且,触发器会创建逻辑,以便在Linq_id列中为每个url_id生成序列值。

请注意,触发器中的逻辑不完整。未解决以下几个问题:1)如果行url_id发生更改,则触发器不会更新Link_id,2)删除行会导致Linq_TB出现空白列序列。