2010-11-18 81 views
8

我有一臺MySQL服務器作爲Microsoft SQL Server 2008中的鏈接服務器。對於鏈接,我使用MySQL ODBC連接器版本5.1.8。當使用OPENQUERY(我發現執行查詢的唯一方式)調用查詢時,會發生問題。簡單的查詢,如從Microsoft SQL Server通過ODBC在MySQL中存在SELECT *問題

SELECT * FROM OPENQUERY(MYSQL, 'SHOW TABLES') 

工作正常。個別列的選擇,例如,

SELECT * FROM OPENQUERY(MYSQL, 'SELECT nr FROM letter') 

工作正常,但SELECT *語法不起作用。查詢:

SELECT * FROM OPENQUERY(MYSQL, 'SELECT * FROM mytable') 

引發錯誤:

Msg 7347, Level 16, State 1, Line 6 OLE DB provider 'MSDASQL' for linked server 'MYSQL' returned data that does not match expected data length for column '[MSDASQL].let_nr'. The (maximum) expected data length is 40, while the returned data length is 0.

我怎樣才能讓SELECT *語法的工作?

回答

11

我經歷了4天的同樣的問題,但最後我發現了爲什麼以及如何解決它。

如果您正在查詢mySQL鏈接的服務器,並且您查詢的表具有char()數據類型,則會發生此問題...這意味着固定長度NOT varchar()。這發生在您的固定長度字段的字符串比sql server預期從odbc獲得的最大長度短時。

修復;轉到MySQL服務器並將數據類型更改爲varchar(),保持原樣...例如,char(10)將其更改爲varchar(10)。

這將工作沒有問題。

請讓我知道,如果這固定它。

塔裏克巴斯塔

+0

嗨,Tarek。非常感謝您的回覆!事實上,恆定長度的char()字段可能是一個問題。我從MySQL導入的字符串遇到了麻煩,他們似乎用零填充。我現在無法檢查,但會在今天或明天嘗試您的解決方案。謝謝! – 2010-12-16 12:06:03

+0

另一方面,使用以下命令:exec('Select * From mytable')AT MYSQL將獲得顯示的數據,但您將無法加入輸出或從中進行選擇,除非您創建臨時表並導出輸出到它。出於這個原因,我個人更喜歡openquery。 – 2010-12-16 14:19:26

+0

我剛剛測試了您的解決方案,實際上將CHAR字段轉換爲VARCHAR會導致錯誤消失。太感謝了! – 2010-12-17 09:58:36

1

我發現這個

"The problem is that one of the fields being returned is a blank or NULL CHAR field. To resolve this in the Mysql ODBC settings select the option "Pad CHAR to Full Length"

看帖子的最後here

+0

我檢查了該選項,重新啓動了SQL Server以獲得較好的效果,但問題仍然存在。 – 2010-11-18 15:08:41

+0

它對MySQL枚舉類型無用。我使用mysql ODBC 5.1驅動程序,mysql服務器5.5,sqlserver 2005. – 2011-09-15 10:21:59

+0

同樣在這裏 - 它不能解決問題。 – Filip 2014-04-01 18:04:54

7

查詢之前執行以下命令似乎幫助:

DBCC TRACEON(8765)

錯誤消息走開,查詢似乎工作正常。

我不確定它是幹什麼的;我在這裏找到它:http://bugs.mysql.com/bug.php?id=46857

奇怪的是,SQL Server變得不穩定,停止響應查詢,並在幾次查詢MySQL服務器後幾分鐘內出現可怕的轉儲崩潰。我不確定這是否需要對DBCC命令做任何事情,所以我仍然對這個問題的其他可能的解決方案感興趣。

+0

你有沒有找到一個新的解決方案? – 2011-09-15 10:26:51

+2

DBCC TRACEON(8765)爲我解決了它。也沒有不穩定性問題。 – 2015-06-10 19:11:58

+0

試試吧,它效果很棒! – petric 2015-07-27 14:31:53

1

另一種方法是使用TRIM()函數在SELECT語句OPENQUERY內。缺點是你必須單獨列出每個字段,但我所做的是創建一個視圖,該視圖調用OPENQUERY,然後在視圖上調用select *。

不理想,但比改變表格上的數據類型更好!

+0

工程就像一個魅力! – Filip 2014-04-01 18:48:44

2

我做了什麼來解決這個問題,因爲我無法修改MySQL數據庫結構只是創建一個演員前景:CAST(call_history.calltype AS CHAR(8)) AS Calltype, 並選擇我的視圖從MSSQL在我的鏈接服務器。

背後的原因是,一些奇怪的類型不與鏈接服務器很好地工作(在我的情況MySQL的枚舉)

1

這裏是我想出了,因爲我無法改變的數據類型的蹩腳的解決方案到varchar,因爲MySQL服務器的數據庫管理員擔心會導致他的腳本出現問題。

在我的MySQL選擇查詢我運行一個case語句來檢查字符串的字符長度,並在字符串「fill up」前添加填充字符到max(在我的情況下是一個字符(6)) 。然後在openquery的select語句中,我將字符剝離。

Select replace(gradeid,'0','') as gradeid from openquery(LINKEDTOMYSQL, ' 
SELECT case when char_length(gradeid) = 0 then concat("000000", gradeID) 
when char_length(gradeID) = 1 then concat("00000", gradeID) 
when char_length(gradeID) = 2 then concat("0000", gradeID) 
when char_length(gradeID) = 3 then concat("000", gradeID) 
when char_length(gradeID) = 4 then concat("00", gradeID) 
when char_length(gradeID) = 5 then concat("0", gradeID) 
else gradeid end as gradeid 
FROM sometableofmine') 

它的工作原理,但它可能是慢...

也許你可以做一個MySQL的函數,將做同樣的邏輯,或想出一個更好的解決方案。

1

我自己也有類似的問題,我通過在單個`樣式引號中包裝列名解決了這個問題。

而不是...

column_name 

...使用... ...

`column_name` 

這樣做有助於MySQL查詢引擎應該列名衝突用鑰匙或reserved- 。字*

而不是使用SELECT * FROM TABLE_NAME的,請嘗試使用引號使用的所有列名:

SELECT `column1`, `column2`, ... FROM TABLE_NAME 

實施例用於正常數據類型列

SELECT * FROM OPENQUERY(MYSQL, 'SELECT `column1`, `column2`,...,`columnN` FROM mytable') 

示例ENUM數據類型列

SELECT * FROM OPENQUERY(MYSQL, 'SELECT `column1`, trim(`column2`) `column2`, `column3`,...,`columnN` FROM mytable') 

*對於那些用於SQL服務器,它是MySQL等效包裹在一個值的方括號,[]

+0

這不提供問題的答案。您可以[搜索類似的問題](https://stackoverflow.com/search),或參考頁面右側的相關和鏈接問題來查找答案。如果你有一個相關但不同的問題,請[提出一個新問題](https://stackoverflow.com/questions/ask),幷包含一個鏈接以幫助提供上下文。請參閱:[提問,獲得答案,無干擾](https://stackoverflow.com/tour) – Sneha 2018-02-20 10:34:59

+0

如果您有新問題,請通過單擊[提問](https://stackoverflow.com/問題/問)按鈕。如果有助於提供上下文,請包含此問題的鏈接。 - [來自評論](/ review/low-quality-posts/18875529) – 2018-02-20 11:04:11

+0

這並沒有真正回答這個問題。如果您有不同的問題,可以通過單擊[提問](https://stackoverflow.com/questions/ask)來提問。您可以[添加賞金](https://stackoverflow.com/help/privileges/set-bounties)在您擁有足夠的[聲譽](https://stackoverflow.com/help/)後吸引更多關注此問題什麼聲譽)。 - [來自評論](/ review/low-quality-posts/18875529) – 2018-02-20 11:37:17