2015-04-23 252 views
1

我正在破壞我的大腦,試圖找出這個查詢有什麼問題。這是爲什麼失敗?

EXECUTE IMMEDIATE ' 
     INSERT INTO [email protected]' || DBLINK || ' 
     (ID, ITEM_ID, ITEM_DESC, QUANTITY, INSERTED_ON, INSERTED_BY) 
     SELECT A.ORDER_ID, A.ITEM_ID, A.ITEM_DESC, A.QUANTITY_SOLD, SYSDATE, ''' || OS_USER || ''' 
     FROM [email protected]' || DBLINK || ' A, [email protected] B 
     WHERE A.ORDER_ID = B.ORDER_ID AND (B.INSERTED_ON >= ''' || V_DATE || ''' OR B.UPDATED_ON >= ''' || V_DATE || ''')'; 

這個查詢是一個過程我發展,以跟蹤與遠程訂單表的變化,「同步」將其與訂單表的保存在ORDERS_HISTORY表中的變化,後者在另一臺服務器上的一部分。因此,ORDERS @ APOLLO應該始終與[email protected]' || DBLINK || '(DB_LINK是動態的,因爲它應該在多個服務器上運行)同步,而更改存儲在[email protected]' || DBLINK || '表中。兩個DB都運行Oracle 11g。

總之,源表在服務器A中,代碼在服務器B中運行,目標表存儲在服務器C中。不能與C「交談」,所以這是最好的我可以來與...一起。

如果我「測試運行」它沒有動態SQL它工作正常,這是它插入預期的行數(250)。但是,當我運行該過程,並且查詢以立即執行運行時,它將插入超過160k(160,000 !!!)行。

什麼可能是錯的?

在此先感謝!

編輯: V_DATE定義爲:

SELECT TO_DATE('01/01/2010 00:00:00', 'DD/MM/YYYY HH24:MI:SS') INTO V_DATE FROM DUAL; 

編輯2:從插入字段列表卸下SYSDATE減少行數的大約一半(大約80K)。仍然太多,但這是一個開始。

回答

1

在構建SQL字符串的這部分中,您依賴於將日期隱式類型轉換爲字符串。

(B.INSERTED_ON >= ''' || V_DATE || ''' OR B.UPDATED_ON >= ''' || V_DATE || ''') 

這意味着行爲取決於會話的當前NLS_DATE_FORMAT以及對列的數據類型進行比較,以得到的字符串。當您以交互方式測試查詢時,您可能是手動輸入日期字符串的格式。

我不確定這是否是問題,但我認爲您應該將其排除爲可能的問題源。

一種方法是確保轉換在兩個方向都是明確的。例如,假設INSERTED_ON是一個日期,做這樣的事情:

'B.INSERTED_ON >= TO_DATE(''' || TO_CHAR(v_date, 'YYYYMMDD') || ''', ''YYYMMDD'')' 

另一種方法,這當然使更多的可讀代碼,並且可在其他方面更好,是使用綁定變量:

'B.INSERTED_ON >= :bind_date' 

增加,在EXECUTE語句的結束,一個USING條款,規定將被綁定的值:

USING v_date 
+0

非常感謝您對您r輸入。不幸的是,它並沒有解決問題:(仍然得到160k行 – DylanW80

+0

說太快了...它實際上解決了問題:)再次感謝戴夫。 – DylanW80