复合键上的SQL Server自动递增

时间:2012-03-12 16:30:12

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

我在SQL Server 2008中有一个带有复合键的表(这是由于各种原因/数据库设计完成的,但主要的是b / c我们正在转向新模式并需要保留数据)。

所以我创建了一个带有外键引用的新表,并且一直致力于迁移数据。数据检索/编辑很简单。现在,我希望能够插入新记录(使用给定的FK值)并能够自动递增新插入的记录ID,并在存储过程中处理所有这些记录。

实施例

表1:(id, type make up the composite key

id   data  type(FK)
1     A      1
2     B      1
1     C      2
2     D      2
3     B      1
4     C      1
3     A      2
4     G      2

现在,如果我有另一个条目(类型2的数据F),我希望能够传入记录数据(data=F,type=2)并拥有存储的proc插入(5,F,2)。 。以线程安全/并发/可扩展的方式(即没有做SELECT MAX(id)...)。有关从SQL Server社区执行此操作的最佳方法的任何想法/想法吗?

3 个答案:

答案 0 :(得分:4)

最简单最安全解决方案只是向表中添加INT IDENTITY列,让SQL Server处理更新标识值的复杂性。这将为您提供真实,正确且可靠的身份价值 - 无论您的type列的价值如何。

在SQL Server 2012中,您可以使用SEQUENCE数据库对象为您需要的type的每个值创建一个序列 - 但是2008版本还没有这样的东西,不幸的是

答案 1 :(得分:1)

这是一种方法,假设您要插入的数据位于另一个表上(表2):

INSERT INTO Table1(id, data, type)
SELECT  ISNULL(B.MaxId,0) + ROW_NUMBER() OVER(PARTITION BY A.type ORDER BY A.data) AS Id,
        A.data,
        A.type
FROM Table2 A
LEFT JOIN (SELECT type, MAX(id) MaxId 
            FROM Table1 
            GROUP BY type) B
ON A.type = B.type

正如@marc_s在评论中所说:在并发负载下使用MAX(Id)方法通常是不安全的

答案 2 :(得分:1)

为什么你总是希望存储这些数据,你总是可以在查询时推导它,并保证它是准确的?

SELECT 
  [type], data, 
  id = ROW_NUMBER() OVER (PARTITION BY [type] ORDER BY data)
FROM dbo.table
ORDER BY [type], id;

您希望这样做,您将需要一个触发器(或多个)来在数据更改时维护表中的信息。例如,运行以下查询时会发生什么:

DELETE dbo.table WHERE data = 'B';

UPDATE dbo.table SET data = 'Z' WHERE data = 'C';

不要存储冗余数据。你认为它会为你节省一些东西,但它所要做的就是需要额外的存储空间并造成不必要的维护悲伤。