Проблема с SELECT * в MySQL через ODBC от Microsoft SQL Server - PullRequest
8 голосов
/ 18 ноября 2010

У меня 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')

выдает ошибку:

Сообщение 7347, уровень 16, состояние 1, строка 6 Поставщик OLE DB 'MSDASQL' для связанного сервер MYSQL вернул данные, которые не соответствует ожидаемой длине данных для столбец '[MSDASQL] .let_nr'. (максимальная) ожидаемая длина данных составляет 40, длина возвращаемых данных - 0.

Как мне заставить работать синтаксис SELECT *?

Ответы [ 7 ]

12 голосов
/ 16 декабря 2010

Я проходил через ту же проблему в течение 4 дней, но, наконец, я нашел, почему и как это исправить.

Эта проблема возникла, если вы запрашиваете связанный сервер MySQL, и у таблицы, которую вы запрашиваете, есть тип данных char () ... Это означает фиксированную длину, а не varchar (). Это происходит, когда поле с фиксированной длиной имеет более короткую строку, чем максимальная длина, которую сервер sql ожидал получить от odbc.

Исправление; перейдите на сервер MySQL и измените тип данных на varchar (), оставив длину как есть ... Например, char (10) измените его на varchar (10).

Это будет работать без проблем.

Пожалуйста, дайте мне знать, если это исправлено.

Тарек Баста

10 голосов
/ 18 ноября 2010

Выполнение следующей команды перед запросами, по-видимому, помогает:

DBCC TRACEON (8765)

Сообщения об ошибках исчезают, и запросы, кажется, работают нормально.

Iхотя я не уверен, что он делает;Я нашел это здесь: http://bugs.mysql.com/bug.php?id=46857

Как ни странно, SQL Server становится нестабильным, перестает отвечать на запросы и, в конечном итоге, вылетает со страшно выглядящими дампами в журналах через несколько минут после нескольких запросов к серверу MySQL.Я не уверен, что это как-то связано с командой DBCC, поэтому я все еще заинтересован в других возможных решениях этой проблемы.

3 голосов
/ 23 января 2012

То, что я сделал, чтобы исправить это, поскольку я не могу изменить структуру базы данных MySQL, - это просто создать представление с приведением типа ex: CAST(call_history.calltype AS CHAR(8)) AS Calltype и выбрать мое представление из MSSQL на моем связанном сервере.

Причина в том, что некоторые странные типы плохо работают со связанным сервером (в моем случае перечисление MySQL)

1 голос
/ 20 февраля 2018

У меня была такая же проблема, как и я, которую я решил, заключив имена столбцов в одинарные кавычки `style.

Вместо ...

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 эквивалент переноса значения в квадратных скобках, [ и ].

1 голос
/ 18 мая 2013

Вот дурацкое решение, которое я придумал, потому что я не могу изменить тип данных на varchar, так как администратор БД для сервера MySQL боится, что это вызовет проблемы с его скриптами.

В моем запросе на выбор в MySQL я запускаю оператор case, проверяющий длину строки в строке и добавляю символ-заполнитель перед строкой, «заполняя ее» до максимума (в моем случае это char (6)). затем в операторе 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 голос
/ 07 декабря 2011

Альтернативой может быть использование функции trim () в вашем операторе SELECT в OPENQUERY.Недостатком является то, что вы должны перечислять каждое поле по отдельности, но я создал представление, которое вызывает OPENQUERY, а затем выполняет select * для представления.

Не идеально, но лучше, чем изменение типов данных в таблицах!1003 *

1 голос
/ 18 ноября 2010

Я нашел это

"Проблема в том, что одно из полей возвращается пустой или NULL CHAR поле. Чтобы решить эту проблему в Mysql В настройках ODBC выберите опцию «Pad» CHAR для полной длины "

Посмотрите на последнее сообщение здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...