2016-01-05 47 views
0

我正在創建一個基本上是兩個數據庫之間完整性檢查的應用程序 - 一個是MSSQL,另一個是舊的提供程序Btrieve。作爲要求的一部分,需要對每個表的所有列進行比較以確保數據匹配。目前我們循環遍歷每個表,獲得兩個數據庫中表的基本計數,然後深入到列中。對於數字字段,我們做一個簡單的SUM,對於文本字段,我們總結每行的列長度。如果這兩個數據庫匹配,這是數據正確遷移的良好指標。'總結'SQL中的日期字段 - 任何想法?

這一切工作正常,但我需要開發類似的日期時間字段。顯然,我們不能真正地總結這些領域,所以我想知道是否有人有辦法解決這個問題的最好方法。我想也許是某個日期以來的秒數,但數字會很大。

還有其他想法嗎?謝謝!

+0

哈希行.... –

回答

0

最直接的答案,我將日期或日期時間字段轉換爲整數格式相同。只要您的格式使用前導零,YYYYMMDD或YYYYMMDDHHmmss就可以正常工作。在SQL Server中,你可以這樣做:

SELECT SUM(CAST(REPLACE(REPLACE(REPLACE(CONVERT(VARCHAR(20),DateTimeColumn,120),' ',''),':',''),'-','') AS BIGINT)) ..... 

或者,也可以將它們轉換爲無論是從某一特定日期('1970-01-01')天數,或幾秒鐘從某一特定日期('1970-01-01 00:00:00')的數量,如果你使用時間。

SELECT SUM(DATEDIFF(DAY,'19700101',DateColumn)) .... 

但是我對Btrieve不太瞭解,不知道格式化日期有哪些功能可用。

+0

非常感謝 - 我和這個解決方案一起去了,它工作得很好! – Chris

-1

我想你可以做這樣的事情在SQL Server端找到中心(「平均」)列的值。然後在Btrieve端使用該值來避免溢出問題,因爲我猜測你更受限制。

-- January 1, 2000 value pulled out of the air as a stab in the dark 
select 
    dataadd(
     second, 
     avg(cast(datediff(datediff(second, '20000101', <data>) as bigint)), 
     '20000101' 
    ) /* find the center */ 

,我不會感到驚訝,如果你不得不求助於浮點型用的Btrieve或您的掃描分割成更小的範圍,以避免中間和值即得太大。你可能想要使用遊標並隨機化行的順序,所以你不會按照導致溢出的排序順序擊中它們。在這一點上,我只是在猜測,因爲我還沒有看到任何數據,而且我對Btrieve的知識是如此古老而且最少。

我也有一種感覺,有些這方面的努力是所有關於非技術性的利益相關者的部分滿足一些不安。我敢肯定,你可以提出更好的校驗和和哈希值,但是這個總結概念是他們可以掌握的,並且可以輕鬆實現,而且更容易快速實現。

0

在數字字段的SQL行中使用「Except」,可以比較兩個表中的日期計數。對於舊來源,您可以使用excel或本地數據庫生成select語句並將其帶入SQL Server。爲了演示目的,我使用了兩個表格並顯示以下例子。

IF EXISTS (SELECT * FROM sys.objects 
      WHERE OBJECT_ID = OBJECT_ID(N'[dbo].[DateCompareOld]') AND 
      TYPE IN (N'U')) 
DROP TABLE [dbo].[DateCompareOld] 
GO 

CREATE TABLE dbo.DateCompareOld 
(
AsOf DATETIME 
) 

INSERT INTO DateCompareOld 
SELECT '01/01/2016' UNION ALL 
SELECT '01/01/2016' UNION ALL 
SELECT '01/01/2016' UNION ALL 
SELECT '01/02/2016' UNION ALL 
SELECT '01/02/2016' UNION ALL 
SELECT '01/02/2016' 


IF EXISTS (SELECT * FROM sys.objects WHERE OBJECT_ID = OBJECT_ID(N'[dbo].[DateCompareNew]') AND TYPE IN (N'U')) 
DROP TABLE [dbo].[DateCompareNew] 
GO 

CREATE TABLE dbo.DateCompareNew 
(
AsOf DATETIME 
) 

INSERT INTO DateCompareNew 
SELECT '01/01/2016' UNION ALL 
SELECT '01/01/2016' UNION ALL 
SELECT '01/01/2016' UNION ALL 
SELECT '01/02/2016' UNION ALL 
SELECT '01/02/2016' UNION ALL 
SELECT '01/02/2016' 

SELECT AsOf,COUNT(*) AsOfCount 
FROM DateCompareOld 
GROUP BY AsOf 
Except 
SELECT AsOf,COUNT(*) AsOfCount 
FROM DateCompareNew 
GROUP BY AsOf 
+2

請解釋一下什麼是錯的downvote呢?。幫助我下次改進它。謝謝。 – CodeEnhancer

+0

我沒有downvote。這個問題並沒有提供對遷移/完整性檢查過程的深入瞭解。我懷疑整個目的是驗證發送到SQL Server的數據是否正確完成。儘管如此,這只是一個受過教育的猜測。 – shawnt00

0

除非在數據庫中使用的行日期範圍極端(如天文星日期,出生和死亡),它應該是一樣有效的日期轉換爲整數。這可以通過幾種方法中的任何一種來完成,並且具有一定的數據庫特定性,但將2016-01-04轉換爲20,160,104將會正常工作。

即使SQL Server允許ORD(date_field)般的表情,以獲得內部表示。但是,這也可以在便攜,系統無關的方式來完成類似

datediff(day, 'January 1, 1901', date_field) 

如果保持幾天的跟蹤就足夠了,或者

datediff(second, 'January 1, 1901', date_field) 

如果需要幾秒鐘跟蹤。

0

也許這是沒有太大的幫助,也許是什麼:

declare @d1 datetime; set @d1 = '2016-01-05 12:09' 
declare @d2 datetime; set @d2 = '1970-04-05 07:09' 
declare @d3 datetime; set @d3 = '1999-12-12 23:05' 
declare @d4 datetime; set @d4 = '1999-12-12 23:06' 

declare @i1 bigint 
declare @i2 bigint 
declare @i3 bigint 
declare @i4 bigint 

select @i1 = convert(bigint, convert(timestamp, @d1)) 
select @i2 = convert(bigint, convert(timestamp, @d2)) 
select @i3 = convert(bigint, convert(timestamp, @d3)) 
select @i4 = convert(bigint, convert(timestamp, @d4)) 

select @i1 
select @i2 
select @i3 
select @i4 

select @i1^@i2^@i3^@i4 
+0

我認爲日期的內部表示可能會在兩個系統之間有所不同。 – shawnt00

+0

@ shawnt00 Yeap ...我完全忘了我們說兩種不同的系統。但也許他可以在他正在開發的應用程序中應用邏輯。一個問題。你是什​​麼意思'內部交涉'? – shadow

+0

您正在使用按位操作,我基本上是指編碼日期值的位模式/值。 – shawnt00