Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 在SQL Server中,如何更改包含记录的表并向每行添加唯一的datetime2列?_Sql Server_Timestamp - Fatal编程技术网

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