2017-01-17 47 views
0

我需要將時間戳列(datetime2)添加到現有的SQL Server數據庫表中。如果我創建列並使用getdate()作爲默認值,則會得到重複值。由於datetime2的精度很高,我認爲它會消除這一點。我想要的引擎可能太快了。在SQL Server中,如何修改包含記錄的表並向每行添加一個唯一的datetime2列?

我不能使用INSERT SELECT,因爲我需要在表格之間具有相同數量的列。我不能做SELECT INTO,因爲上一張表需要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 
+0

一種方式是創建一個DATETIME2列可空,使用延時功能中柱,一次在NOT NULL列插入唯一日期時間值,改變該列使其非空 – vamsi

回答

1

這是一個時間,其中光標是真正有用的,因爲它增添了幾分延遲,你可以擴展,如果需要。試試這樣的代碼:

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 
1

更快的選項可能是準備一個重複的集合,然後改變它是唯一的。

有2種方法可以做到這一點。

  1. 在平行表中準備唯一日期,然後複製。
  2. 允許重複,插入記錄,然後將數據更改爲唯一值,然後將該列更改爲唯一。

示例代碼如下:

--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 
相關問題