从Microsoft SQL Server通过ODBC在MySQL中选择*时出现问题
我在MicrosoftSQLServer2008中有一个MySQL服务器作为链接服务器。对于链接,我使用MySQL ODBC连接器版本5.1.8。使用从Microsoft SQL Server通过ODBC在MySQL中选择*时出现问题,mysql,sql-server,odbc,Mysql,Sql Server,Odbc,我在MicrosoftSQLServer2008中有一个MySQL服务器作为链接服务器。对于链接,我使用MySQL ODBC连接器版本5.1.8。使用OPENQUERY(我发现的执行查询的唯一方法)调用查询时,会出现问题。简单查询,例如 SELECT * FROM OPENQUERY(MYSQL, 'SHOW TABLES') 干得好。选择单个列,例如 SELECT * FROM OPENQUERY(MYSQL, 'SELECT nr FROM letter') 也可以正常工作,但SELEC
OPENQUERY
(我发现的执行查询的唯一方法)调用查询时,会出现问题。简单查询,例如
SELECT * FROM OPENQUERY(MYSQL, 'SHOW TABLES')
干得好。选择单个列,例如
SELECT * FROM OPENQUERY(MYSQL, 'SELECT nr FROM letter')
也可以正常工作,但SELECT*语法不起作用。查询:
SELECT * FROM OPENQUERY(MYSQL, 'SELECT * FROM mytable')
引发一个错误:
信息7347,16级,状态1,第6行
链接的OLE DB提供程序“MSDASQL”
服务器“MYSQL”返回的数据
与的预期数据长度不匹配
列'[MSDASQL].let\u nr'。这个
(最大)预期数据长度为40,
而返回的数据长度为0
如何使SELECT*语法起作用?我找到了这个
“问题是其中一个领域
返回的字符为空或空
字段。以在Mysql中解决此问题
ODBC设置选择“Pad”选项
“字符到完整长度”
查看最后一篇文章,在查询似乎有帮助之前执行以下命令: DBCC TRACEON(8765) 错误消息消失了,查询似乎工作正常 我不知道它是干什么的,我在这里找到的:
奇怪的是,SQL Server变得不稳定,停止响应查询,最后在多次查询MySQL服务器几分钟后,日志中出现可怕的转储。我不确定这是否与DBCC命令有关,因此我仍然对解决此问题的其他可能解决方案感兴趣。我正在浏览同样的问题持续了4天,但最终我找到了解决的原因和方法 如果您查询的是mySQL链接服务器,并且您查询的表具有数据类型char()…这意味着固定长度而不是varchar()。当您的固定长度字段的字符串短于sql server期望从odbc获得的最大长度时,会发生此问题 修复方法:转到MySQL服务器,将数据类型更改为varchar(),保持长度不变……例如,char(10)将其更改为varchar(10) 这不会有问题 请让我知道这是否解决了它
Tarek Basta另一种选择是在OPENQUERY中的SELECT语句中使用trim()函数。缺点是必须单独列出每个字段,但我所做的是创建一个调用OPENQUERY的视图,然后在该视图上执行SELECT*
这并不理想,但比更改表上的数据类型要好!由于我无法修改MySQL数据库结构,所以我所做的就是创建一个以cast ex:
cast(call_history.calltype AS CHAR(8))作为calltype的视图,
并从链接服务器的MSSQL中选择我的视图
背后的原因是一些奇怪的类型不能很好地与链接服务器(在我的例子中是MySQL枚举)配合使用。我提出了一个糟糕的解决方案,因为我无法将数据类型更改为varchar,因为MySQL服务器的db管理员担心这会导致他的脚本出现问题
在我的MySQL select查询中,我运行了一个case语句,检查字符串的字符长度,并在字符串“filling it up”前面添加一个填充字符,直到最大值(在我的例子中,它是一个char(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函数来实现同样的逻辑,或者提出一个更优雅的解决方案。我自己也遇到过类似的问题,我通过将列名用单引号括起来解决了这个问题
而不是
column_name
…使用
`column_name`
如果列名与关键字或保留字冲突,这样做有助于MySql查询引擎*
不要使用SELECT*FROM TABLE\u NAME
,而是尝试使用带引号的所有列名:
SELECT `column1`, `column2`, ... FROM TABLE_NAME
普通数据类型列的示例
SELECT * FROM OPENQUERY(MYSQL, 'SELECT `column1`, `column2`,...,`columnN` FROM mytable')
SELECT * FROM OPENQUERY(MYSQL, 'SELECT `column1`, trim(`column2`) `column2`, `column3`,...,`columnN` FROM mytable')
枚举数据类型列的示例
SELECT * FROM OPENQUERY(MYSQL, 'SELECT `column1`, `column2`,...,`columnN` FROM mytable')
SELECT * FROM OPENQUERY(MYSQL, 'SELECT `column1`, trim(`column2`) `column2`, `column3`,...,`columnN` FROM mytable')
*对于那些使用Sql Server的人来说,它相当于将一个值包装在方括号中,[
和]
我选中了选项,重新启动了SQL Server,但问题仍然存在。它对mysql枚举类型无效。我使用mysql ODBC 5.1驱动程序、mysql Server 5.5、sqlserver 2005。嗨,塔瑞克。非常感谢您的回复!确实是恒定长度字符()字段可能有问题。从MySQL导入的字符串似乎被零填充,我遇到了问题。我现在无法检查,但今天或明天将尝试您的解决方案。谢谢!另一方面,使用以下命令:exec('Select*from mytable'))MYSQL将显示数据,但除非您创建临时表并将输出导出到其中,否则您将无法加入输出或从中进行选择。因此,我个人更喜欢openquery。我刚刚测试了您的解决方案,事实上,将CHAR字段转换为VARCHAR会消除错误。万分感谢上帝,我无法更改字段类型!不必更改表本身的数据类型,只需在查询上转换它:CAST(MyColumn AS VARCHAR(1))DBCC TRACEON(8765)为我解决了它。也没有不稳定的问题。像一个魅力一样工作,但如何工作?这并没有提供问题的答案。你可以,或参考页面右侧的相关和链接问题来找到答案。如果你有一个相关但不同的问题,并包括一个指向此问题的链接,以帮助提供上下文。请参阅:I如果您有新问题,请单击按钮提问。如果有助于提供上下文,请添加指向此问题的链接。@Knickerless Noggins这不是问新问题,这是关于在页面顶部提出的Gintauts Miliauskas的答案,我有经验在从MSSQL Openquery检索MySql数据时,我遇到了同样的错误,我只是写了我是如何找到答案的