Известные проблемы с драйвером ODBC в Linux и macOS

Скачать драйвер ODBC

Эта статья содержит список известных проблем в Microsoft ODBC Driver 13, 13.1, 17, 18 for SQL Server на платформах Linux и macOS. В ней также представлены шаги по устранению неполадок с подключением.

Известные проблемы

Дополнительные проблемы будут опубликованы в блоге о драйверах SQL Server.

  • Из-за ограничений системной библиотеки Alpine Linux поддерживает меньше кодировок символов и языковых стандартов. Например, недоступна кодировка en_US.UTF-8. Дополнительные сведения см. в статье musl libc - functional differences from glibc (musl libc — функциональные отличия от glibc).

  • В Windows, Linux и macOS символы из кодировки области личных символов (PUA) или символов, определяемых конечными пользователями (EUDC), могут преобразовываться по-разному. Преобразования, выполняемые на сервере в Transact-SQL, используют библиотеку преобразований Windows. Преобразования в драйвере используют библиотеки функций преобразования Windows, Linux или macOS. Каждая из библиотек может давать разные результаты при выполнении преобразований. Дополнительные сведения см. в статье End-User-Defined and Private Use Area Characters (Символы, определяемые конечными пользователями, и символы области личных символов).

  • Если кодировка клиента — UTF-8, то диспетчер драйверов не всегда выполняет преобразование из UTF-8 в UTF-16 должным образом. При наличии в строке недопустимых символов UTF-8 сейчас происходит повреждение данных. Символы ASCII сопоставляются правильно. Диспетчер драйверов пытается выполнить такое преобразование при вызове SQLCHAR-версий интерфейса API ODBC (например, SQLDriverConnectA). Диспетчер драйверов не пытается выполнить такое преобразование при вызове SQLWCHAR-версий API ОDВC (например, SQLDriverConnectW).

  • Параметр ColumnSize функции SQLBindParameter указывает на число символов в типе SQL, а BufferLength — это число байтов в буфере приложения. Тем не менее, если используется тип данных SQL varchar(n) или char(n), приложение связывает параметр как SQL_C_CHAR для типа C или SQL_C_VARCHAR для типа SQL, а клиент использует кодировку UTF-8, может появиться ошибка "Усечение данных строки справа" от драйвера, даже когда значение ColumnSize согласовано с размером типа данных на сервере. Эта ошибка возникает по той причине, что в результате преобразования между кодировками символов длина данных может измениться. Например, символ правого апострофа (U+2019) кодируется в CP-1252 как один байт 0x92, а в UTF-8 — как трехбайтовая последовательность 0xe2 0x80 0x99.

Например, если используется кодировка UTF-8 и вы указали значение 1 для BufferLength и ColumnSize выходного параметра в функции SQLBindParameter, а затем пытаетесь получить предыдущий символ, хранящийся в столбце char(1) на сервере (в кодировке CP-1252), то драйвер попытается преобразовать его в трехбайтовую кодировку UTF-8, однако результат не поместится в однобайтовый буфер. Значение ColumnSize сравнивается с BufferLength в SQLBindParameter перед выполнением преобразования между разными кодовыми страницами в клиенте и на сервере. Поскольку ColumnSize для 1 меньше, чем BufferLength , например, для 3, драйвер выдает ошибку. Чтобы избежать этой ошибки, убедитесь в том, что после преобразования данные поместятся в указанный буфер или столбец. Обратите внимание на то, что для типа varchar(n) значение ColumnSize не может превышать 8000.

Устранение неполадок с подключением

Если установить подключение к SQL Server с помощью драйвера ODBC не удается, следующие сведения помогут вам определить проблему.

Чаще всего проблема подключения связана с наличием двух установленных копий диспетчера драйверов UnixODBC. Выполните поиск libodbc*.so* в /usr. Если отображается более одной версии файла, (возможно) установлено несколько диспетчеров драйверов. Приложение может использовать неправильную версию.

Включите журнал соединений, добавив в файл /etc/odbcinst.ini раздел со следующими элементами:

[ODBC]
Trace = Yes
TraceFile = (path to log file, or /dev/stdout to output directly to the terminal)

Если возникает другой сбой подключения и файл журнала отсутствует, возможно, на компьютере имеются две копии диспетчера драйверов. В противном случае должны выводиться примерно следующие данные журнала:

[ODBC][28783][1321576347.077780][SQLDriverConnectW.c][290]
        Entry:
            Connection = 0x17c858e0
            Window Hdl = (nil)
            Str In = [DRIVER={ODBC Driver 18 for SQL Server};SERVER={contoso.com};Trusted_Connection={YES};WSID={mydb.contoso.com};AP...][length = 139 (SQL_NTS)]
            Str Out = (nil)
            Str Out Max = 0
            Str Out Ptr = (nil)
            Completion = 0
        UNICODE Using encoding ASCII 'UTF8' and UNICODE 'UTF16LE'

Если для кодировки символов ASCII используется не UTF-8, например:

UNICODE Using encoding ASCII 'ISO8859-1' and UNICODE 'UCS-2LE'

В этом случае установлено больше одного диспетчера драйверов и приложение использует неверный либо сборка диспетчера драйверов была выполнена некорректно.

При использовании драйверов версии до 17.8 у некоторых пользователей macOS возникает следующая ошибка:
(Эта ошибка была устранена в версии драйвера 17.9 и выше.)

[08001][Microsoft][ODBC Driver 17 for SQL Server]SSL Provider: [OpenSSL library could not be loaded, make sure OpenSSL 1.0 or 1.1 is installed]
[08001][Microsoft][ODBC Driver 17 for SQL Server]Client unable to establish connection (0) (SQLDriverConnect)

Эта ошибка может возникать при установленной библиотеке OpenSSL 3.0. Обычно OpenSSL устанавливается с помощью Brew и содержит двоичные файлы openssl, openssl@1.1, и openssl@3.

Чтобы исправить эту ошибку, измените символическую ссылку двоичного файла openssl на openssl@1.1.

rm -rf $(brew --prefix)/opt/openssl
version=$(ls $(brew --prefix)/Cellar/openssl@1.1 | grep "1.1")
ln -s $(brew --prefix)/Cellar/openssl@1.1/$version $(brew --prefix)/opt/openssl

Дополнительные сведения об устранении неполадок подключения см. в статьях:

Дальнейшие действия

Инструкции по установке драйвера ODBC см. в следующих статьях.

Дополнительные сведения см. в рекомендациях по программированию и заметках о выпуске.