2010-11-18 94 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

相关问题