MySQL中的SELECT *通过Microsoft SQL Server的ODBC出现问题

时间:2010-11-18 14:46:01

标签: mysql sql-server odbc

我有一个MySQL服务器作为Microsoft SQL Server 2008中的链接服务器。对于链接,我使用MySQL ODBC Connector版本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,Level 16,State 1,Line 6   OLE DB提供程序' MSDASQL'为了链接   服务器' MYSQL'返回的数据   不匹配的预期数据长度   列' [MSDASQL] .let_nr'。该   (最大)预期数据长度为40,   而返回的数据长度为0。

如何使SELECT *语法有效?

7 个答案:

答案 0 :(得分:12)

我在4天内遇到了同样的问题,但最后我找到了解决问题的原因和方法。

如果您正在查询mySQL链接服务器并且您查询的表具有数据类型char(),则会发生此问题...这意味着固定长度NOT varchar()。当你的固定长度字段的字符串短于sql server期望从odbc获得的最大长度时,会发生这种情况。

修复;转到MySQL服务器并将数据类型更改为varchar(),保留长度,例如,实例,char(10)将其更改为varchar(10)。

这没问题。

如果修好了,请告诉我。

Tarek Basta

答案 1 :(得分:9)

在查询之前执行以下命令似乎有帮助:

DBCC TRACEON(8765)

错误消息消失,查询似乎工作正常。

我不确定它做了什么;我在这里找到了它:http://bugs.mysql.com/bug.php?id=46857

奇怪的是,SQL Server变得不稳定,停止响应查询,最后在几次向MySQL服务器发出查询后几分钟内在日志中崩溃并发现可怕的转储。我不确定这是否必须对DBCC命令做任何事情,所以我仍然对这个问题的其他可能解决方案感兴趣。

答案 2 :(得分:2)

由于无法修改MySQL数据库结构,我所做的是解决这个问题,只需创建一个带有ex:CAST(call_history.calltype AS CHAR(8)) AS Calltype的视图, 并在我的链接服务器中从MSSQL中选择我的视图。

背后的原因是一些奇怪的类型与链接服务器不兼容(在我的例子中是MySQL枚举)

答案 3 :(得分:1)

我发现了这个

  

“问题在于其中一个领域   被返回是一个空白或NULL CHAR   领域。要在Mysql中解决这个问题   ODBC设置选择“Pad”选项   CHAR到全长“

查看上一篇文章here

答案 4 :(得分:1)

另一种方法是在OPENQUERY中的SELECT语句中使用trim()函数。缺点是您必须单独列出每个字段,但我所做的是创建一个调用OPENQUERY的视图,然后在视图上执行select *。

不理想,但比改变表格上的数据类型更好!

答案 5 :(得分:1)

这是我提出的一个糟糕的解决方案,因为我无法将数据类型更改为varchar,因为MySQL服务器的数据库管理员担心它会导致脚本出现问题。

在我的MySQL select查询中我运行一个case语句检查字符串的字符长度,并在字符串“填充”到最大值(在我的例子中是一个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功能,或者提出一个更优雅的解决方案。

答案 6 :(得分:1)

我自己遇到了类似的问题,我通过将列名包装在单个`样式引号中来解决。

而不是......

    img {
      width: 100%;
      display: block;
      resize: both;
    }

... ...使用

  <html>
    <head>
<title>Untitled-1</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body bgcolor="#FFFFFF" leftmargin="0" topmargin="0" marginwidth="0" marginheight="0">
<!-- Save for Web Slices (Untitled-1) -->
<table id="Table_01" width="600" height="901" border="0" cellpadding="0" cellspacing="0">
	<tr>
		<td colspan="4">
			<img src="images/test_01.jpg" width="600" height="226" alt=""></td>
	</tr>
	<tr>
		<td colspan="2">
			<img src="images/test_02.jpg" width="309" height="228" alt=""></td>
		<td colspan="2" rowspan="2">
			<img src="images/test_03.jpg" width="291" height="290" alt=""></td>
	</tr>
	<tr>
		<td colspan="2">
			<img src="images/test_04.jpg" width="309" height="62" alt=""></td>
	</tr>
	<tr>
		<td rowspan="2">
			<img src="images/test_05.jpg" width="216" height="384" alt=""></td>
		<td colspan="2">
			<img src="images/test_06.jpg" width="186" height="34" alt=""></td>
		<td rowspan="2">
			<img src="images/test_07.jpg" width="198" height="384" alt=""></td>
	</tr>
	<tr>
		<td colspan="2">
			<img src="images/test_08.jpg" width="186" height="350" alt=""></td>
	</tr>
	<tr>
		<td>
			<img src="images/spacer.gif" width="216" height="1" alt=""></td>
		<td>
			<img src="images/spacer.gif" width="93" height="1" alt=""></td>
		<td>
			<img src="images/spacer.gif" width="93" height="1" alt=""></td>
		<td>
			<img src="images/spacer.gif" width="198" height="1" alt=""></td>
	</tr>
</table>
<!-- End Save for Web Slices -->
</body>
</html>

这样做有助于MySql查询引擎应该使用键或保留字与列名冲突。*

不要使用column_name ,而是尝试使用带引号的所有列名:

`column_name`

普通数据类型列的示例

SELECT * FROM TABLE_NAME

ENUM数据类型列的示例

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

*对于那些习惯于使用Sql Server的人来说,MySql相当于用方括号SELECT * FROM OPENQUERY(MYSQL, 'SELECT `column1`, `column2`,...,`columnN` FROM mytable') SELECT * FROM OPENQUERY(MYSQL, 'SELECT `column1`, trim(`column2`) `column2`, `column3`,...,`columnN` FROM mytable') 包装一个值。