【问题标题】:Problem with SELECT * in MySQL through ODBC from Microsoft SQL ServerSELECT * 在 MySQL 中通过 Microsoft SQL Server 的 ODBC 出现问题
【发布时间】:2011-05-12 02:05:01
【问题描述】:

我有一个 MySQL 服务器作为 Microsoft SQL Server 2008 中的链接服务器。对于链接,我使用 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')

引发错误:

消息 7347,第 16 级,状态 1,第 6 行 用于链接的 OLE DB 提供程序“MSDASQL” 服务器“MYSQL”返回的数据 与预期的数据长度不匹配 列“[MSDASQL].let_nr”。这 (最大)预期数据长度为 40, 而返回的数据长度为0。

如何使 SELECT * 语法起作用?

【问题讨论】:

    标签: mysql sql-server odbc


    【解决方案1】:

    我遇到同样的问题 4 天,但最终我找到了原因以及如何解决它。

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

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

    这将毫无问题。

    如果这解决了问题,请告诉我。

    塔雷克·巴斯塔

    【讨论】:

    • 嗨,塔雷克。非常感谢您的回复!实际上,恒定长度的 char() 字段可能是个问题。我遇到了从 MySQL 导入的字符串的问题,它们似乎被零填充。我现在无法检查,但会在今天或明天尝试您的解决方案。谢谢!
    • 另一方面,使用以下命令: exec('Select * From mytable') AT MYSQL 将显示数据,但您将无法加入输出或从中选择,除非您创建一个临时表并将输出导出到它。出于这个原因,我个人更喜欢 openquery。
    • 我刚刚测试了您的解决方案,确实将 CHAR 字段转换为 VARCHAR 会使错误消失。谢谢一百万!
    • 天哪,我无法更改字段类型!
    • 无需更改表本身的数据类型,只需在查询中进行转换:CAST(MyColumn AS VARCHAR(1))
    【解决方案2】:

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

    DBCC TRACEON(8765)

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

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

    奇怪的是,在对 MySQL 服务器进行几次查询后几分钟,SQL Server 变得不稳定,停止响应查询并最终崩溃,日志中出现看起来很吓人的转储。我不确定这是否与 DBCC 命令有关,因此我仍然对解决此问题的其他可能解决方案感兴趣。

    【讨论】:

    • DBCC TRACEON(8765) 为我解决了这个问题。也没有不稳定的问题。
    • 像魅力一样工作,但如何?
    【解决方案3】:

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

    背后的原因是一些奇怪的类型不能很好地与链接服务器(在我的例子中是 MySQL 枚举)一起工作

    【讨论】:

    • 不需要在视图中进行,直接在查询中进行即可。
    【解决方案4】:

    我找到了这个

    “问题是其中一个字段 返回的是空白或 NULL CHAR 场地。在 Mysql 中解决这个问题 ODBC设置选择选项“Pad CHAR 到全长"

    看最后一个帖子here

    【讨论】:

    • 我检查了该选项,重新启动了 SQL Server,但问题仍然存在。
    • 它对 mysql 枚举类型没用。我使用 mysql ODBC 5.1 驱动程序,mysql server 5.5,sqlserver 2005。
    【解决方案5】:

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

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

    【讨论】:

      【解决方案6】:

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

      在我的 MySQL 选择查询中,我运行一个 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 函数,或者提出更优雅的解决方案。

      【讨论】:

        【解决方案7】:

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

        而不是...

        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 将值括在方括号中,[]

        【讨论】:

        • 这没有提供问题的答案。您可以search for similar questions,或参考页面右侧的相关和链接问题找到答案。如果您有一个相关但不同的问题,ask a new question,并包含指向此问题的链接以帮助提供上下文。见:Ask questions, get answers, no distractions
        • 我也遇到过类似的问题,通过上面的回答解决了
        • 如果您有新问题,请点击 按钮提出问题。如果有助于提供上下文,请包含指向此问题的链接。
        • @Knickerless-Noggins 这不是问一个新问题,这是关于在页面顶部提出的 Gintautas Miliauskas 的答案,我在从 MSSQL Openquery 检索 MySql 数据时遇到了同样的错误,我只是写了我是如何发现问题以及如何解决的。
        • @Knickerless-Noggins 感谢您编辑我的帖子,现在更清楚了,我现在知道如何回答,干杯....!!!
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-01-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多