我在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社区执行此操作的最佳方法的任何想法/想法吗?
答案 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';
不要存储冗余数据。你认为它会为你节省一些东西,但它所要做的就是需要额外的存储空间并造成不必要的维护悲伤。