我使用OLEDB源調用存儲過程以通過在存儲中的三個SELECT語句之間執行UNION來獲取一組標記爲I
U
或D
的行程序。更改存儲過程中的選擇順序會影響SSIS掛起問題
A是一個填充了每天晚上從遺留系統帶來的數據的表格。 B是我們系統的數據,我們希望不斷更新遺留系統的數據。
SET NOCOUNT ON;
-- entries in A that dont exist in B need to be inserted into B
SELECT
A.ID,
B.ID,
A.data1,
A.data2,
A.data3,
A.data4,
F1.ID as Fkey1,
F2.ID as Fkey2,
'I' as InsertUpdateDeactivateFlag
FROM A
LEFT JOIN B ON A.val = B.val
LEFT JOIN F1 ON A.f1val = F1.val
LEFT JOIN F2 ON A.f2val = F2.val
WHERE B.ID is null
UNION ALL
-- entries in A that do exist in B that have different field values
SELECT
A.ID,
B.ID,
A.data1,
A.data2,
A.data3,
A.data4,
F1.ID as Fkey1,
F2.ID as Fkey2,
'U' as InsertUpdateDeactivateFlag
FROM A
INNER JOIN B ON A.val = B.val
LEFT JOIN F1 ON A.f1val = F1.val
LEFT JOIN F2 ON A.f2val = F2.val
WHERE
A.data1 <> B.data1 OR
A.data2 <> B.data2 OR
A.data3 <> B.data3 OR
A.data4 <> B.data4 OR
F1.ID <> B.Fkey1 OR
F2.ID <> B.Fkey2
UNION ALL
-- entries in B that dont exist in A should have Active set to 0
SELECT
A.ID,
B.ID,
B.data1,
B.data2,
null as data3, -- dont need this value for deactivates
null as data4, -- dont need this value for deactivates
B.Fkey1,
B.Fkey2,
'D' as InsertUpdateDeactivateFlag
FROM A
RIGHT JOIN B ON A.val = B.val
WHERE A.ID is null
然後我做使用該標誌以引導行至三個OLEDB命令,對於每行(插入,更新,或失活)來執行存儲過程中的一個的條件劃分。這三個程序寫入表B.
如果只有幾十行通過我的SSIS包,它工作正常。但是,當我們消除表B並重新填充(幾十萬個插入)時,該包會掛起。它只是掛起,沒有錯誤信息,沒有失敗。 OLEDB源讀取除最後幾行外的所有行(大約需要700行,每次都是相同的數),通過剩餘的流饋送行,然後掛起。我的同事說,它實際上在75分鐘左右之後完成。
存儲過程在SSMS中完美運行,並且每次都會在幾秒鐘內返回整個結果集。從來沒有任何問題,除了在SSIS。
現在奇怪的部分是,如果我將第三個SELECT語句(停用)從最後的結果集合移到union的第一個結果集,一切正常,並且程序包在大約3分鐘內執行!咦?另外,如果我不對停用進行連接,只需從其中一個表中返回所有行,它也可以正常工作。爲什麼SSIS會關心這個連接,或者它會怎麼知道呢?我也嘗試在外部SELECT包裝UNIONs無濟於事。
我們已經檢查過SQL Server Profiler,查詢執行正常,沒有鎖等。據我瞭解,在開始將行放入管道之前,SSIS已經從OLEDB源中獲取所有數據。因此,寫入我在SQL Server上選擇的同一個表所產生的併發問題不應該是一個問題,因爲在包開始處理之前讀取已完成(請糾正我,如果這是錯誤的)。
就好像SSIS在UNIONs按照特定順序分析存儲過程時不正確。是這樣嗎?有沒有人遇到類似的情況?或者有人可以在這個過程中看到我應該在哪裏尋找問題?
在實際的存儲過程中,SELECT項中有CASE語句,WHERE子句項中的ISNULL()以及WHERE子句項和SELECT項中的其他UDF調用,以防萬一。
謝謝。
這很有趣。我會試試看看會發生什麼。 – 2010-07-21 16:29:43
拋出ORDER BY,無論順序(asc/desc)如何工作。添加ORDER BY會增加執行計劃的時間,也許最後一個SELECT會在插入開始之前完成。我將研究這種特定連接(停用)的含義以及爲什麼它可能在同時插入時掛起。 – 2010-07-22 11:34:56