我有一个基本上是一个语句的 sql 表。
现在假设我在表中的记录有一个日期和一个身份列,该列是自动编号的,并定义了交易在前端显示给客户端的顺序。
问题是在插入过程中,一些数据丢失了,两个日期之间的一些交易丢失了。
我需要将数据插入到表中,但我需要在日期之间而不是在表的末尾插入它们。如果我进行正常插入,数据将出现在表的末尾而不是我指定的日期,因为标识列是自动编号的,并且无法更新。
我有一个基本上是一个语句的 sql 表。
现在假设我在表中的记录有一个日期和一个身份列,该列是自动编号的,并定义了交易在前端显示给客户端的顺序。
问题是在插入过程中,一些数据丢失了,两个日期之间的一些交易丢失了。
我需要将数据插入到表中,但我需要在日期之间而不是在表的末尾插入它们。如果我进行正常插入,数据将出现在表的末尾而不是我指定的日期,因为标识列是自动编号的,并且无法更新。
使用SET IDENTITY_INSERT (table) ON
,您可以强制 SQL Server 让您将任意值插入 IDENTITY 列 - 但无法更新IDENTITY 列。
无论如何,一些差距有什么大问题?是的,这可能是一个“美容”问题——但你真的想在美容问题上花费多少麻烦和努力?条目的顺序仍然是给定的 - 即使有差距。
再说一遍:有什么大不了的?IDENTITY 列保证会不断增加——这就是他们所保证的全部。对于 99% 的情况,这已经足够了......
为什么不在用户界面中显示按日期排序的记录,而不是按主键?
好的,如果您真的想这样做(我个人认为更改 UI 中的排序日期将比更新数据库中的主键值更容易,但无论如何......)。这应该可以工作,假设您没有在任何外键约束中使用主键值(如果是,那么您需要确保这些约束已ON UPDATE CASCADE
设置)
SET IDENTITY_INSERT tablename ON
UPDATE tablename SET
primary_key = primay_key + 1
WHERE
primary_key >= <the primary key where you want to insert the new date>
INSERT INTO tablename
(primary_key, date, ...)
VALUES
(<the primary key to insert>, <the date to insert>, ...)
SET IDENTITY_INSERT tablename OFF
但是,我强烈建议您在尝试此操作之前备份您的数据库。
只是出于好奇,每个日期是一个ID吗?您的回答暗示了这一点,因此,如果是这样,请将 Identity 列替换为计算列,该计算列定义为从任意起点开始的日期差(以天为单位)?
DECLARE @EXAMPLE TABLE
(
[Date] DATE,
ID AS DATEDIFF(Day, '1 Jan 2010', [Date])
)
INSERT INTO @EXAMPLE([Date])
VALUES (GETDATE()), (GETDATE()+1), (GETDATE()+2)
SELECT * FROM @EXAMPLE