从Microsoft SQL Server通过ODBC在MySQL中执行SELECT * 时出现问题

eeq64g8w  于 2022-12-17  发布在  SQL Server
关注(0)|答案(7)|浏览(323)

我在Microsoft SQL Server 2008中使用MySQL服务器作为链接服务器。对于链接,我使用MySQL ODBC连接器版本5.1.8。当使用OPENQUERY(我发现的执行查询的唯一方法)调用查询时,会出现问题。

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

工作良好。单个列的选择,例如,

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

也可以正常工作,但SELECT * 语法不起作用。查询:

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

引发错误:
Msg 7347,级别16,状态1,行6链接服务器“MYSQL”的OLE DB访问接口“MSDASQL "返回的数据与列”[MSDASQL].let_nr“的预期数据长度不匹配。预期(最大)数据长度为40,而返回的数据长度为0。
如何使SELECT * 语法工作?

hzbexzde

hzbexzde1#

如果查询MySQL链接服务器,并且查询的表具有数据类型char(),则会发生此问题。这意味着固定长度,而不是varchar()。当固定长度字段的字符串短于SQL Server期望从ODBC获取的最大长度时,会发生此问题。
要修复此问题,请转到MySQL服务器并将数据类型更改为varchar(),保持长度不变。例如,将char(10)更改为varchar(10)

gijlo24d

gijlo24d2#

在查询之前执行以下命令似乎会有所帮助:
数据库中心跟踪(8765)
错误消息消失了,查询似乎工作正常。
但我不确定它能做什么我在这里找到的:http://bugs.mysql.com/bug.php?id=46857
奇怪的是,SQL Server变得不稳定,停止响应查询,最后在对MySQL服务器进行了几次查询后几分钟崩溃,日志中出现了可怕的转储。我不确定这是否与DBCC命令有关,所以我仍然对这个问题的其他可能解决方案感兴趣。

jgovgodb

jgovgodb3#

由于我不能修改MySQL数据库结构,我所做的就是用一个cast ex创建一个视图:CAST(call_history.calltype AS CHAR(8)) AS Calltype,然后从链接服务器的MSSQL中选择我的视图。
其背后的原因是一些奇怪的类型不能很好地与链接服务器一起工作(在我的例子中是MySQL枚举)

34gzjxbg

34gzjxbg4#

我发现了这个
问题是返回的字段之一是空或NULL CHAR字段。若要在Mysql ODBC设置中解决此问题,请选择“将CHAR填充为全长”选项。
看最后一篇文章here

okxuctiv

okxuctiv5#

另一种方法是在OPENQUERY内的SELECT语句中使用trim()函数,缺点是必须单独列出每个字段,但我所做的是创建一个调用OPENQUERY的视图,然后在该视图上执行select *。
不是很理想,但比更改表上的数据类型要好!

nimxete2

nimxete26#

这是我想出的一个蹩脚的解决方案,因为我无法将数据类型更改为varchar,因为MySQL服务器的数据库管理员担心这会导致他的脚本出现问题。
在我的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函数来做同样的逻辑,或者想出一个更优雅的解决方案。

b09cbbtk

b09cbbtk7#

我自己也遇到过类似的问题,我通过将列名用单引号括起来解决了这个问题。
而不是...

column_name

...用...

`column_name`

这样做有助于MySql查询引擎在列名与关键字或保留字冲突时发挥作用。*
不要使用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 Server的函数,它相当于MySql中将值括在方括号[]中。

相关问题