MS SQL, проблема с кодировкой при чтении через ODBC
Добавлено: 21 окт 2016, 11:37
Приветствую, уважаемые форумчане!
Было проделано следующее:
В базе MSSQL (пробовались версии 2008/2012/2014) создана таблица:
Кодировка скуля - Cyrillic_General_CI_AS. Гугление подсказывает, что должно быть utf16
ERP система, генерирует поля fullname,name,secret,partner(для внутренних целей),regexten.
Были сделаны настройки:
res_odbc.conf
extconfig.conf
func_odbc.conf (использую для проверки через консоль *)
/etc/odbcinst.ini
/etc/odbc.ini
Перепробовал кучу сочетаний параметров tds_version (7,0 7,1 7,2 7,4 8,0) charset (UTF8 UTF16 CP1251) use utf-16 (ставил yes no) - мою проблему это не решает
o freetds:
/usr/local/etc/freetds.conf (не уверен, что он вообще используется если freetds библиотека вызывается из unixODBC)
Пользователи успешно "регистрируются" и могут звонить. Но проблема с русскими символами, хранящимися в mssql базе. Таким образом у вызываемого абонента отображаются "знаки вопроса" в количестве русских символов поля fullname. Тоже самое вижу в консоли *, если добавить noop(${CALLERID(name)}).Если fullname на английском - проблем нет.
Причем если запустить тот же запрос через консоль ОС - то результат в правильной кодировке:
Если через родную для freetds утилиту tsql - тоже всё в русской кодировке. А вот если обратиться с тем же запросом в консоле астериска через res_odbc - вот такая шляпа:
iconv --list выдаёт полотно кодировок. Пробовал на sql серверах (2008/2012/2014) с разным ОС (2008/2012, русифицированными/нерусифицированнами). Первоначально тип данных внутри sql был varchar, а не nvarchar, но разницы никакой. Пробовал менять locale для пользователя, запускающего астериск - не помогает. Пробовал обновить до последних стабильных версий unixODBC и freetds скомпилировав из исходников - такая же песня. Хотел было уже поставить нативный майкрософтовский клиент, но центос на котором работает * - x86, а sqlncli по-видимому требует x64 разрядность. Если конечно решение не будет найдено - перенастрою всё на х64. Но появился чисто спортивный интерес победить эту проблему.
Еще одна странная деталь. Объяснить её не могу (видимо не выучил матчасть):
Если использовать в odbc.ini параметр tds_version 7.2 7.3 7.4,то в консоле ОС строка обрезается до четырех первых символов. Для значений 7.0 7.1 8.0 - передается полностью. Но на поведение астериска изменения этих параметров не влияют. Астериск стабильно выдает все русские символы строки ввиде "знаков вопроса" .
Что еще добавить? Asterisk 11.8, Centos 6.5. Архитектурно поменять mssql на mysql не получится, ибо ERP разрабы не захотели тратить время на изучение связок с mysql. В этом я их не виню. Поэтому имеем, что имеем. Уважаемые коллеги, подскажите пожалуйста что еще можно поправить/проверить чтобы астериск увидел русскую кодировку?
Было проделано следующее:
В базе MSSQL (пробовались версии 2008/2012/2014) создана таблица:
Код: Выделить всё
use IPtel;
CREATE TABLE Numbers (
[id] int IDENTITY(1,1) NOT NULL,
[name] nvarchar(MAX) NULL,
[ipaddr] nvarchar(MAX) NULL,
[port] int NULL,
[regseconds] int NULL,
[user] nvarchar(MAX) NULL,
[fullcontact] nvarchar(MAX) NULL,
[regserver] nvarchar(MAX) NULL,
[useragent] nvarchar(MAX) NULL,
[lastms] int NULL,
[host] nvarchar(MAX) NOT NULL DEFAULT 'dynamic',
[type] nvarchar(MAX) NOT NULL DEFAULT 'friend',
[context] nvarchar(MAX) NOT NULL DEFAULT 'BDD-INCOMING',
[permit] nvarchar(MAX) NOT NULL DEFAULT '0.0.0.0/0',
[deny] nvarchar(MAX) NULL,
[secret] nvarchar(MAX) NULL,
[md5secret] nvarchar(MAX) NULL,
[remotesecret] nvarchar(MAX) NULL,
[transport] nvarchar(MAX) NOT NULL DEFAULT 'udp',
[dtmfmode] nvarchar(MAX) NOT NULL DEFAULT 'rfc2833',
[directmedia] nvarchar(MAX) NOT NULL DEFAULT 'no',
[nat] nvarchar(MAX) NOT NULL DEFAULT 'force_rport,comedia',
[callgroup] nvarchar(MAX) NULL,
[pickupgroup] nvarchar(MAX) NULL,
[language] nvarchar(MAX) NULL,
[allow] nvarchar(MAX) NOT NULL DEFAULT '!all,alaw',
[disallow] nvarchar(MAX) NULL,
[insecure] nvarchar(MAX) NULL,
[trustrpid] nvarchar(MAX) NULL,
[progressinband] nvarchar(MAX) NULL,
[promiscredir] nvarchar(MAX) NULL,
[useclientcode] nvarchar(MAX) NULL,
[accountcode] nvarchar(MAX) NULL,
[setvar] nvarchar(MAX) NULL,
[callerid] nvarchar(MAX) NULL,
[amaflags] nvarchar(MAX) NULL,
[callcounter] nvarchar(MAX) NULL,
[busylevel] int NULL,
[allowoverlap] nvarchar(MAX) NULL,
[allowsubscribe] nvarchar(MAX) NULL,
[videosupport] nvarchar(MAX) NULL,
[maxcallbitrate] int NULL,
[rfc2833compensate] nvarchar(MAX) NULL,
[mailbox] nvarchar(MAX) NULL,
[session-timers] nvarchar(MAX) NULL,
[session-expires] int NULL,
[session-minse] int NULL,
[session-refresher] nvarchar(MAX) NULL,
[t38pt_usertpsource] nvarchar(MAX) NULL,
[regexten] nvarchar(MAX) NULL,
[fromdomain] nvarchar(MAX) NULL,
[fromuser] nvarchar(MAX) NULL,
[qualify] nvarchar(MAX) NULL,
[ip] nvarchar(MAX) NULL,
[rtptimeout] int NULL,
[rtpholdtimeout] int NULL,
[sendrpid] nvarchar(MAX) NULL,
[outboundproxy] nvarchar(MAX) NULL,
[callbackextension] nvarchar(MAX) NULL,
[registertrying] nvarchar(MAX) NULL,
[timert1] int NULL,
[timerb] int NULL,
[qualifyfreq] int NULL,
[constantssrc] nvarchar(MAX) NULL,
[contactpermit] nvarchar(MAX) NULL,
[contactdeny] nvarchar(MAX) NULL,
[usereqphone] nvarchar(MAX) NULL,
[textsupport] nvarchar(MAX) NULL,
[faxdetect] nvarchar(MAX) NULL,
[buggymwi] nvarchar(MAX) NULL,
[auth] nvarchar(MAX) NULL,
[fullname] nvarchar(MAX) NULL,
[trunkname] nvarchar(MAX) NULL,
[cid_number] nvarchar(MAX) NULL,
[callingpres] nvarchar(MAX) NULL,
[mohinterpret] nvarchar(MAX) NULL,
[mohsuggest] nvarchar(MAX) NULL,
[parkinglot] nvarchar(MAX) NULL,
[hasvoicemail] nvarchar(MAX) NULL,
[subscribemwi] nvarchar(MAX) NULL,
[vmexten] nvarchar(MAX) NULL,
[autoframing] nvarchar(MAX) NULL,
[rtpkeepalive] int NULL,
[call-limit] int NOT NULL DEFAULT '2',
[g726nonstandard] nvarchar(MAX) NULL,
[ignoresdpversion] nvarchar(MAX) NULL,
[allowtransfer] nvarchar(MAX) NULL,
[dynamic] nvarchar(MAX) NULL,
[partner] nvarchar(MAX) NULL,
[defaultuser] nvarchar(MAX) NULL,
)
ERP система, генерирует поля fullname,name,secret,partner(для внутренних целей),regexten.
Были сделаны настройки:
res_odbc.conf
Код: Выделить всё
[SIGMA]
enabled=>yes
dsn=>SIGMA
pooling=>no
limit=>5
pre-connect=>yes
username=>userformsl
password=>passwordforsql
sanitysql => select 1
idlecheck => 600000
backslash_is_escape => no
share_connections => no
Код: Выделить всё
[settings]
sippeers => odbc,SIGMA,Numbers
Код: Выделить всё
[SIGMA]
dsn=SIGMA
readsql=SELECT fullname FROM numbers WHERE name='testlogin'
Код: Выделить всё
[FreeTDS]
Description = FreeTDS ODBC driver for MSSQL
Driver = /usr/local/lib/libtdsodbc.so
Setup = /usr/local/lib/libtdsodbc.so
FileUsage = 1
Threading = 2
Код: Выделить всё
[SIGMA]
description = Asterisk ODBC for MSSQL
driver = FreeTDS
server = SIGMA
Username = userformsl
Pssword = passwordforsql
port = 1433
database = IPtel
tds_version = 7.0
language = us_english
charset = UTF8
use utf-16 = yes
o freetds:
Код: Выделить всё
tsql -C
Compile-time settings (established with the "configure" script)
Version: freetds v1.00.15
freetds.conf directory: /usr/local/etc
MS db-lib source compatibility: no
Sybase binary compatibility: no
Thread safety: yes
iconv library: yes
TDS version: auto
iODBC: no
unixodbc: yes
SSPI "trusted" logins: no
Kerberos: no
OpenSSL: yes
GnuTLS: no
MARS: no
Код: Выделить всё
[global]
client charset = UTF-8
tds version = auto
text size = 64512
Причем если запустить тот же запрос через консоль ОС - то результат в правильной кодировке:
Код: Выделить всё
echo "SELECT fullname FROM numbers WHERE name='testlogin'" | isql SIGMA userformsl passwordforsql
----------------------------+
| fullname |
+---------------------------+
| Иван Иванов |
+---------------------------+
SQLRowCount returns 1
Код: Выделить всё
odbc read ODBC_SIGMA readsql exec
fullname ???? ??????
Returned 1 row. Query executed on handle 0 [SIGMA]
Еще одна странная деталь. Объяснить её не могу (видимо не выучил матчасть):
Если использовать в odbc.ini параметр tds_version 7.2 7.3 7.4,то в консоле ОС строка обрезается до четырех первых символов. Для значений 7.0 7.1 8.0 - передается полностью. Но на поведение астериска изменения этих параметров не влияют. Астериск стабильно выдает все русские символы строки ввиде "знаков вопроса" .
Что еще добавить? Asterisk 11.8, Centos 6.5. Архитектурно поменять mssql на mysql не получится, ибо ERP разрабы не захотели тратить время на изучение связок с mysql. В этом я их не виню. Поэтому имеем, что имеем. Уважаемые коллеги, подскажите пожалуйста что еще можно поправить/проверить чтобы астериск увидел русскую кодировку?