我在一台SQL上設了Linked Server指向ORACLE,利用

INSERT INTO SqlTable
    SELECT * FROM LinkedOracleServer..MySchema.MyTable

的方法從ORACLE端匯資料過來,一路相安無事。

直到今天同事改了ORACLE上的Schema,將USERNAME由VARCHAR2改為NVARCHAR2,結果在倒資料時冒出以下錯誤:

Msg 7356, Level 16, State 1, Line 5
The OLE DB provider "MSDAORA" for linked server "LinkedOracleServer" supplied inconsistent metadata for a column. The column "USERNAME" (compile-time ordinal 9) of object ""MySchema"."MyTable"" was reported to have a "DBTYPE" of 130 at compile time and 129 at run time.

Google了一下,有人說是9.2.0.4之前版本的Bug,我想起設Linked Server時用的是Microsoft OLEDB Provider for ORACLE,記得上回在處理中文問題時,它跟Oracle Provider for OLE DB產生的結果很不相同,所以我先想做的就是換一下Provider試試手氣。更換後,原本的問題就消失了。

正以為之後會一帆風順,卻又被潑了一盆冷水...

在ORACLE與SQL的有一組對應的Table,Schema/Primary Key設定都相同,但明明在ORACLE都是UNIQUE的資料,倒入SQL的對應Table卻出現Primary Key重複的錯誤。我反覆利用GROUP BY ... HAVING COUNT(*) > 1檢查ORACLE上的Table不下五次,明明就沒有重複資料呀,鬼月都過了還這樣。

後來,使出撒手鐧,將SQL上Table Primary Key設定先移除,倒完資料再用GROUP BY ... HAVING COUNT(*) > 1檢查,終於揪出凶手。繼上回發現ORACLE會將空字串當成NULL,今天又發現SQL Server會將VARCHAR欄位後方的空白自動RTRIM掉,而ORACLE則不會。今天出錯的原因就在於ORACLE上,有人手滑在設了兩筆資料,PK分別為'AAA'及'AAA ',在ORACLE上被視為兩筆,等要轉入SQL時,'AAA '被RTRIM成'AAA',就發生了PK重複的慘劇。找到苦主,請他把手滑的重複資料清除,總算搞定了原本應輕鬆做完的工作。

整合系統的日子真是多采多姿呀~~~


Comments

# by dave

>SQL Server會將VARCHAR欄位後方的空白自動RTRIM掉, >而ORACLE則不會。 太歡樂,那麼自動的的東西真是惡夢

# by ABC

varchar的定義本來就是忽視後方的空白... 這起事件是很多原因造成的... 輸入介面沒有防呆... 轉換DB的時候沒有選好資料格式... 程式沒有空白清掉... 都是原因...跟有沒有auto無關

# by 一個看不懂的人

INSERT INTO SqlTable SELECT * FROM LinkedOracleServer..MySchema.MyTable 針對上述 INSERT語法,我想請問幾個問題: (1) SqlTable需要事先建立嗎? (2) MySchema代表什麼?是類似 dbo 或 建立 MyTable的 userid? 謝謝你的回答!

# by Jeffrey

to 看不懂的人, 1) 不需要事先建立 2) 多半就是ORACLE建立該資料表的User Id

# by 一個看不懂的人

感謝ㄋ的回答! 在 SQL Server 2008 執行下列語法 INSERT INTO POI SELECT * FROM LinkedOracleServer..MySchema.MyTable SQL Server回應「無效的物件名稱 'POI' 」 但是在 SQL Server建立 POI這個 TABLE,則上述語法能夠正常執行。 想請問要如何設定,才能在沒有建立 TABLE情況下,執行上述語法。 如果想透過排程執行上述語法,要如何做?

# by 一個看不懂的人

終於解決其中一個問題 ㄡ測試的結果: INSERT INTO SqlTable SELECT * FROM LinkedOracleServer..MySchema.MyTable 執行這語法的前提是SqlTable已經存於 SQL Server中 如果SQL Server沒有SqlTable資料表改用 select * into SqlTable from LinkedOracleServer..MySchema.MyTable 關於想透過排程執行上述語法,要如何做? 還是沒有頭緒,希望高手能幫幫忙!

# by nolem

oracle原本是varchar 還是varchar2 ? 如果是varchar2 應該是會自動rtirm .

Post a comment