Sql server 在SQL Server中,如何更改包含记录的表并向每行添加唯一的datetime2列?
我需要将时间戳列(Sql server 在SQL Server中,如何更改包含记录的表并向每行添加唯一的datetime2列?,sql-server,timestamp,Sql Server,Timestamp,我需要将时间戳列(datetime2)添加到现有的SQL Server数据库表中。如果创建列并使用getdate()作为默认值,则会得到重复的值。由于datetime2的精度很高,我认为它可以消除这一点。发动机可能太快了,不适合我想做的事情 我不能使用INSERT-SELECT,因为我需要表之间的列数相同。我无法在中选择,因为上一个表需要datetime2,这是最初的问题。我还尝试在创建列的同时创建索引。我不能,因为重复项是在创建索引之前创建的,而索引(设置为不允许重复项)。我试过了。这些都失败
datetime2
)添加到现有的SQL Server数据库表中。如果创建列并使用getdate()
作为默认值,则会得到重复的值。由于datetime2的精度很高,我认为它可以消除这一点。发动机可能太快了,不适合我想做的事情
我不能使用INSERT-SELECT
,因为我需要表之间的列数相同。我无法在中选择,因为上一个表需要datetime2,这是最初的问题。我还尝试在创建列的同时创建索引。我不能,因为重复项是在创建索引之前创建的,而索引(设置为不允许重复项)。我试过了。这些都失败了
如何更改表并添加新的datetime2列,并使用getdate()中的所有唯一值(或其他日期/时间函数)填充该列
编辑:根据Vamsi的评论,我尝试:
INSERT
SELECT
WAITFOR DELAY '00:00:10.000'
The duplicate key value is (2017-01-17 11:59:03.7030000)
我收到一份复印件,所以我做错了什么
编辑:根据笑维吉尔(谢谢)的回答,我这样做了
DECLARE @dt datetime2(7),
@dt2 datetime2(7),
@create_dt datetime2(7)
declare db_cursor cursor for
select create_dt from mytable;
OPEN db_cursor
FETCH NEXT FROM db_cursor
INTO @create_dt
WHILE (@@FETCH_STATUS = 0)
begin
SET @dt = GETDATE()
WHILE @dt = @dt2
BEGIN
WAITFOR DELAY '00:00:00.123'
SET @dt = GETDATE()
END
update mytable set create_dt = @dt where current of db_cursor
set @dt2 = @dt
FETCH NEXT FROM db_cursor into @create_dt
end
close db_cursor
deallocate db_cursor
这是光标实际有用的一次,因为它增加了一点延迟,如果需要可以扩展。请尝试以下代码:
DECLARE @dt datetime2(7),
@dt2 datetime2(7)
DECLARE @MyTableID int
SET @dt = getdate()
SET @dt2 = GETDATE()
DECLARE cx CURSOR FOR
SELECT MyTableID
FROM MyTable
WHERE MyDateTimeColumn IS NULL
FOR UPDATE OF MyDateTimeColumn
Open cx
FETCH NEXT FROM cx
INTO @MyTableID
WHILE @@FETCH_STATUS = 0
BEGIN
SET @dt = GETDATE()
WHILE @dt = @dt2
BEGIN
WAITFOR DELAY '00:00:00.001'
SET @dt = GETDATE()
END
UPDATE MyTable
SET MyDateTimeColumn = @dt
WHERE CURRENT OF cx
SET @dt2 = @dt
FETCH NEXT FROM cx
INTO @MyTableID
END
CLOSE cx
DEALLOCATE cx
这是光标实际有用的一次,因为它增加了一点延迟,如果需要可以扩展。请尝试以下代码:
DECLARE @dt datetime2(7),
@dt2 datetime2(7)
DECLARE @MyTableID int
SET @dt = getdate()
SET @dt2 = GETDATE()
DECLARE cx CURSOR FOR
SELECT MyTableID
FROM MyTable
WHERE MyDateTimeColumn IS NULL
FOR UPDATE OF MyDateTimeColumn
Open cx
FETCH NEXT FROM cx
INTO @MyTableID
WHILE @@FETCH_STATUS = 0
BEGIN
SET @dt = GETDATE()
WHILE @dt = @dt2
BEGIN
WAITFOR DELAY '00:00:00.001'
SET @dt = GETDATE()
END
UPDATE MyTable
SET MyDateTimeColumn = @dt
WHERE CURRENT OF cx
SET @dt2 = @dt
FETCH NEXT FROM cx
INTO @MyTableID
END
CLOSE cx
DEALLOCATE cx
一个更快的选择可能是准备一个复制集,然后将其更改为唯一集 有两种方法可以做到这一点
--Create a holding table
DROP TABLE dbo.TimeTest
CREATE TABLE dbo.TimeTest(ID BIGINT IDENTITY(1,1)
,Val Float
,Dtm DATETIME2 DEFAULT(GETDATE() )
);
GO
--Insert Test Data (creating duplicates)
INSERT INTO dbo.TimeTest(Val) VALUES(RAND())
GO 1000
--Show duplicate values
SELECT * FROM dbo.TimeTest ORDER BY ID
--Remove the Duplication
;WITH cte AS (
SELECT
A.Dtm
,ROW_NUMBER() OVER(PARTITION BY Dtm ORDER BY ID) AS Rnk
FROM
dbo.TimeTest A
)
UPDATE cte
SET
Dtm = DATEADD(MICROSECOND,Rnk-1,Dtm)
ALTER TABLE dbo.TimeTest ADD CONSTRAINT Dtm UNIQUE(Dtm)
--Show unique values
SELECT * FROM dbo.TimeTest ORDER BY ID
一个更快的选择可能是准备一个复制集,然后将其更改为唯一集 有两种方法可以做到这一点
--Create a holding table
DROP TABLE dbo.TimeTest
CREATE TABLE dbo.TimeTest(ID BIGINT IDENTITY(1,1)
,Val Float
,Dtm DATETIME2 DEFAULT(GETDATE() )
);
GO
--Insert Test Data (creating duplicates)
INSERT INTO dbo.TimeTest(Val) VALUES(RAND())
GO 1000
--Show duplicate values
SELECT * FROM dbo.TimeTest ORDER BY ID
--Remove the Duplication
;WITH cte AS (
SELECT
A.Dtm
,ROW_NUMBER() OVER(PARTITION BY Dtm ORDER BY ID) AS Rnk
FROM
dbo.TimeTest A
)
UPDATE cte
SET
Dtm = DATEADD(MICROSECOND,Rnk-1,Dtm)
ALTER TABLE dbo.TimeTest ADD CONSTRAINT Dtm UNIQUE(Dtm)
--Show unique values
SELECT * FROM dbo.TimeTest ORDER BY ID
一种方法是创建一个可为null的datetime2列,使用delay函数将唯一的datetime值插入该列,一旦该列不为null,则更改该列使其为非null。一种方法是创建一个可为null的datetime2列,使用delay函数将唯一的datetime值插入到列中,一旦列不为null,则更改列使其为非null