2011-08-04 206 views
2

我有一個每晚從SS400數據庫系統導出TON數據的SSIS過程。由於AS400 DB軟件中存在錯誤,因此將重複項密鑰插入數據表中。每次將新的副本添加到AS400表時,它都會導致我晚上的導出過程中斷。這個問題已經從滋擾變成了問題。如何在準特有數據密鑰上創建主密鑰?

我需要的是有一個選項,只插入唯一的數據。如果有重複,請選擇第一個遇到的重複行的行。有沒有SQL語法可以幫助我做到這一點?我知道DISTINCT ROW子句,但在我的情況下不起作用,因爲對於大多數違規記錄,除組成PK的字段外,整個數據是非唯一的。

就我而言,我的主鍵在我的SQL Server數據庫緩存中保持唯一性,而不是擁有數據的完整快照更爲重要。有什麼我可以做的強制這個約束出口在SSIS/SQL Server與崩潰的過程?

編輯

讓我進一步明確了我的要求。我需要的是確保導出的SQL Server表中的數據與維護AS400數據表的數據保持相同的密鑰。換句話說,創建唯一的行計數標識符將不起作用,也不會在沒有主鍵的情況下插入所有數據。

如果AS400軟件中的錯誤允許錯誤的重複PK,我想要忽略這些行,或者最好只選擇具有重複鍵的行中的一個,但不能同時選擇這兩個行。

該SELECT語句可能發生在我的SSIS項目中的SELECT語句中,該語句通過ODBC連接連接到大型機。

我懷疑我的問題可能沒有「簡單」解決方案。然而,我希望我錯了。

回答

2

由於您使用SSIS,您必須使用OLE DB Source來從AS400中的數據,你會使用OLE DB Destination將數據插入到SQL Server。

讓我們假設你沒有任何轉換

Data Flow Task

添加Sort transformation的OLE DB源之後。在排序轉換中,底部有一個複選框選項,可根據給定的一組列值刪除重複的行。檢查所有字段,但不要選擇來自AS400的主鍵。這將消除重複的行,但會插入仍然需要的數據。

Sort

我希望這是你在找什麼。

+0

我應該只檢查與PK關聯的列嗎?當我執行任務時,我仍然受到PK侵犯。 – RLH

+0

另外,假設我確實有轉換,我會做什麼不同?在我的情況下,我有一個轉換,從每個文本字段的末尾截斷填充間距。 – RLH

+0

這似乎是正確的答案,但我仍然得到PK Vialation錯誤。我進行了三重檢查 - 我沒有選中所有的PK字段(在這種情況下,有8個字段),並且在SORT轉換之後放置了我的轉換。我可以錯過任何東西嗎? – RLH

1

SQL Server 2005及以上:

SELECT * 
FROM (
     SELECT *, 
       ROW_NUMBER() OVER (PARTITION BY almost_unique_field ORDER BY id) rn 
     FROM import_table 
     ) q 
WHERE rn = 1 
+0

我可能需要編輯我的問題,但這不是我的意思。我想說的是,如果一個字段應該是唯一的,但不是,有沒有辦法獲得一些數據?是的,可以添加一個行號。但是我需要的是找到一種方法來鎖定我在SQL Server中唯一的獨特PK,儘管它們在源數據庫中並不是唯一的。 – RLH

+0

@RLH:請發佈一些示例輸入和輸出數據,因爲您想查看它。 – Quassnoi

+0

這可以在執行SQl任務的SSIS中使用。我總是將原始數據放入臨時表中,然後在設置變換之前執行類似的任務。您也可以將複製的記錄移動到異常表中,以便稍後檢查不同的數據以查看您導入的數據是否需要更改或用於發送回源以告訴它們他們有數據問題。它還有助於將排除在異常表中的數據存儲起來,因爲遲早有人會想知道爲什麼他們看不到他們知道的其他系統中的某些內容。 – HLGEM

1

有幾種選擇。

如果您在主鍵上使用IGNORE_DUP_KEY(http://www.sqlservernation.com/home/creating-indexes-with-ignore_dup_key.html)選項,SQL將發出警告並且只有重複記錄將失敗。

您也可以對數據進行分組/彙總,但這可能會非常昂貴。我的意思是:

SELECT Id, MAX(value1), MAX(value2), MAX(value3) etc 

另一種選擇是(在此爲一個有效的後加入和簇)添加標識列到你的臨時表中,然後創建一個臨時表的映射。映射表是:

CREATE TABLE #mapping 
( 
    RowID INT PRIMARY KEY CLUSTERED, 
    PKIN INT 
) 

INSERT INTO #mapping 
SELECT PKID, MIN(rowid) FROM staging_table 
GROUP BY PKID 

INSERT INTO presentation_table 
SELECT S.* 
FROM Staging_table S 
    INNER JOIN #mapping M 
     ON S.RowID = M.RowID 
0

如果我理解正確的話,你有重複的PK有在其他領域不同的數據。

首先,將來自其他數據庫的數據放入登臺表中。如果我這樣做,我發現更容易研究進口(尤其是大型)的問題。實際上我使用兩個臨時表(對於這種情況我強烈推薦它),一個使用原始數據,另一個僅使用我想要導入到系統中的數據。

現在您可以使用並執行SQL任務來獲取每個鍵的記錄之一(請參閱@Quassnoi瞭解如何執行此操作,以便您可能需要根據自己的情況調整查詢)。就我個人而言,我將身份證放入暫存表中,以便我可以確定哪些是重複數據的首次發生或最後發生。然後將您爲每個鍵選擇的記錄放入第二個登臺表中。如果您使用的是異常表,請複製您未轉移的記錄,並且不要忘記異常的原因碼(例如「重複鍵」)。

既然您在臨時表中每個鍵只有一條記錄,那麼接下來的任務就是決定如何處理不是唯一的其他數據。如果同一客戶有兩個不同的商戶地址,您選擇哪一個?這是業務規則定義的問題,嚴格來說不是SSIS或SQL代碼。當數據需要在兩條記錄之間合併時,您必須爲您如何選擇數據定義業務規則(您正在做的是等價於刪除過程)。如果幸運的話,可以通過日期字段或其他方式來確定哪些是最新或最舊的數據,這是他們希望您使用的數據。在這種情況下,一旦你選擇了一條記錄,你就完成了初始化變換。

儘管您可能需要不同的規則才能選擇正確的字段,在這種情況下,您可以在數據流或Exec SQl任務中編寫SSIS轉換以選擇正確的數據並更新登臺表。

一旦你有想要導入的確切記錄,然後做數據流移動到正確的生產表。