erlang: odbc - не может получить правильные результаты запроса в юникоде из mssql - PullRequest
0 голосов
/ 26 июня 2019

Что я пытаюсь: - просто сделайте выбор с помощью erlang-odbc из эликсира и выведите все результаты в консоль.

Окружающая среда: моя сторона

  • Red Hat Enterprise LinuxСерверная версия 7.6 (Maipo)
  • unixODBC-devel (ням)
  • Elixir 1.8.2 (скомпилировано с Erlang / OTP 20)
  • Erlang / OTP 21
  • erlang-odbc R16B (ням)
  • (любой) драйвер mssql
  • (или) драйвер FreeTds 1.1.6 (скомпилирован из исходников --with-unixodbc)

target

  • mssql server 2016
  • таблица


    CREATE TABLE db_name.dbo.rating (
        [Year] int NULL,
        Code varchar(256) COLLATE Cyrillic_General_CI_AS NULL,
        Name nvarchar(4000) COLLATE Cyrillic_General_CI_AS NULL,
        GroupeCode varchar(256) COLLATE Cyrillic_General_CI_AS NULL,
        GroupeName nvarchar(4000) COLLATE Cyrillic_General_CI_AS NULL,
        Cost numeric(38,5) NOT NULL,
        PrchasesCount int NULL
        ) GO

nvarchar : имя_символа_имя: UNICODE collation_name: Cyrillic_General_CI_AS

varchar : имя_символа: cp1251 collation_name: Cyrillic_General_CI_AS

код эликсира выглядит так:

conn_str = 
    "SERVER=XX.XX.XX.XX,1433;" <>
     #tried this too! "DRIVER={ODBC Driver 17 for SQL Server};" <>
    "DRIVER=FreeTDS;" <>
    "DATABASE=db_name;UID=bot;PWD=XXXXXX;" 
|> to_charlist

 statement = "select top(3) Name from Rating order by Cost desc" |> to_charlist

 {:ok, pid}=:odbc.connect(conn_str,[])

 {:selected, col_names, rows} = :odbc.sql_query(pid, statement)

и после всех попыток, у меня есть что-то вроде этого в результате

{:selected, ['Name'],
 [
   {<<32, 4, 48, 4, 49, 4, 62, 4, 66, 4, 75, 4, 32, 0, 65, 4, 66, 4, 64, 4, 62,
      4, 56, 4, 66, 4, 53, 4, 59, 4, 76, 4, 61, 4, 75, 4, 53, 4, 32, 0, 63, 4,
      62, 4, 32, ...>>},
   {<<16, 4, 64, 4, 53, 4, 61, 4, 52, 4, 48, 4, 32, 0, 63, 4, 48, 4, 65, 4, 65,
      4, 48, 4, 54, 4, 56, 4, 64, 4, 65, 4, 58, 4, 62, 4, 51, 4, 62, 4, 32, 0,
      66, 4, ...>>},
   {<<35, 4, 65, 4, 59, 4, 67, 4, 51, 4, 56, 4, 32, 0, 63, 4, 62, 4, 32, 0, 64,
      4, 53, 4, 58, 4, 67, 4, 59, 4, 76, 4, 66, 4, 56, 4, 50, 4, 48, 4, 70, 4,
      56, ...>>}
 ]}

вместо правильного кириллического текста

это не случайные числа!результат всегда один и тот же.

Драйвер MS дает тот же результат, что и FreeTDS

что еще я пробовал

  • изменение параметров conn binary_strings:: on / off
  • настройка опции client charset = UTF-8 в freetds.conf (в глобальном разделе)
  • чесать голову
  • , используя: функции Юникода для чтения << data >>
  • использование is_binary () для полученных номеров возвращает true

Вопросы

  • какой тип данных я получаю?
  • почему данные неверныдекодированный?
  • какое приложение отвечает за это?
  • как я могу это исправить?некоторая часть журнала freetds здесь (о iconv)
iconv.c:326:tds_iconv_open(0x1e02330, UTF-8)
iconv.c:186:local name for ISO-8859-1 is ISO-8859-1
iconv.c:186:local name for UTF-8 is UTF-8
iconv.c:186:local name for UCS-2LE is UCS-2LE
iconv.c:186:local name for UCS-2BE is UCS-2BE
iconv.c:348:setting up conversions for client charset "UTF-8"
iconv.c:350:preparing iconv for "UTF-8" <-> "UCS-2LE" conversion
iconv.c:389:tds_iconv_open: done
iconv.c:785:setting server single-byte charset to "CP1251"

1 Ответ

0 голосов
/ 27 июня 2019

Если вы используете SQL Server 2019, вам нужно использовать параметры сортировки, которые заканчиваются на _UTF8, а не _AS.Здесь есть полная статья с деталями типов сортировки:

https://docs.microsoft.com/en-us/sql/relational-databases/collations/collation-and-unicode-support?view=sql-server-2017#utf-8-support

Предыдущий до MSSQL 2019,

Я знаю, что это работает для Python 3.

...