Конференция "Базы" » Параметры и mysql-connector-odbc-5.1.5 [D6, MySQL]
 
  • aleks-ran © (07.08.09 16:48) [0]
    Уважаемые мастера, подскажите решение следующей проблемы:
    При выполнении запроса
    UPDATE Clients SET FirstName='Иванов' WHERE LoginId='asdf'
    все работает просто замечательно, но если использую
    UPDATE Clients SET FirstName=:FN WHERE LoginId='asdf'  , затем ес-но
    Query1.Parameters.ParamByName('FN').Values:='Иванов';
    Query1.ExecSQL;
    в таблицу записываются крякозябры - Eaaiia
    Таблица Clients  в кодировке UTF8,  доступ через ADO компоненты
    Знаю что через  mysql-connector-odbc-3.51 все работает, но нужно именно через 5.1
  • sniknik © (07.08.09 20:50) [1]
    > в кодировке UTF8
    попробуй сам преобразовать значение присваиваемое параметру в UTF8...

    > Знаю что через  mysql-connector-odbc-3.51 все работает, но нужно именно через 5.1
    там главное не версия, главное что какие то драйвера "русифицированы", помню тоже подбирал подходящие. подошли те которые рекомендовали на mysql.ru.
  • aleks-ran © (07.08.09 21:27) [2]
    Я тут немного разобрался, как выйти из положения, но ясности это не добавило. :)
    AdoQuery1.ConnectionString:=Provider=MSDASQL.1;Persist Security Info=False;Data Source=MySQLSource";
    ...
    AdoQuery1.Open; - все работает, все замечательно - буквы РУССКИЕ!
    Затем с этой же строкой подключения
     ADOCommand1.Parameters.ParamValues['FN']:=Edit1.Text;
     ADOCommand1.Execute;

     ADOQuery1.Close;
     ADOQuery1.Open; - текст крякозябры

    Но если для ADOCommand сделать так:
     ADOCommand1.ConnectionString:='Provider=MSDASQL.1;Persist Security Info=False;Data Source=MySQLSource;Extended Properties="charset=utf8"';
     ADOCommand1.Parameters.ParamValues['FN']:=AnsiToUtf8(Edit1.Text);
     ADOCommand1.Execute;
     ADOQuery1.Close;
     ADOQuery1.Open;  все снова работает.

    Так вот, получается для ADOQuery - одна строка подключения, а для ADOCommand - другая , с явным указанием кодировки. Почему?
    Как-то несимметричненько :)
  • sniknik © (07.08.09 21:42) [3]
    что то что другое неправильно, должен быть отдельный "коннектор". а строка у компонента... можно даже не рассматривать.
    вот сделай коннектор, подключи к нему оба компонента, потом и смотри разницу.
  • aleks-ran © (07.08.09 22:37) [4]
    А я сразу так и делал. Смотри первоначальный вопрос.
    Потом было просто лень бросать на форму второй ADOConnection
    Впрочем, с ним ситуация такая же как в [2]
  • sniknik © (07.08.09 23:32) [5]
    > Впрочем, с ним ситуация такая же как в [2]
    т.е. оба "смотрят" в одно соединение, одинаковый запрос, одинаковый параметр (тип параметра если установлен),  одинаковое значение задается, и у одного компонента пишется по русски, у другого нет?
    верится с трудом, тем более ADOQuery через такой же ADOCommand запросы выполняет, что и на палитре.
  • aleks-ran © (07.08.09 23:52) [6]
    Вы не поняли, смотрите первоначальный вопрос.
    Все компоненты смотрели в один и тот же ADOConnection
    1. запросы, возвращающие набор данных работают нормально.
    2. запросы на изменение (update) работают нормально, но только если SET FIO='иванов'
    3. тот же запрос, если написан с использованием параметров, т.е SET FIO=:F и затем:
    Query1.Parameters.ParamByName('F').Values:='Иванов';
    Query1.ExecSQL;
    пишут в базу данных крякозябры
    Помогает только указание в строке подключения Extended Properties="charset=utf8"'; и затем Parameters.ParamValues['FN']:=Edit1.Text;
    но если с этой строкой подключения сделать запрос на выборку то тогда уже с ним в гриде будут крякозябры
  • aleks-ran © (08.08.09 00:07) [7]
    Виноват, Parameters.ParamValues['FN']:=AnsiToUtf8(Edit1.Text);
  • sniknik © (08.08.09 10:43) [8]
    > Вы не поняли
    да нет, все я понял, понял, что разных вариантах разные результаты, и общая кодировка не совпадает с кодировкой параметров...
    (если посмотришь внимательно я еще в [1] советовал рабочий вариант с самостоятельной перекодировкой, т.к. подозревал именно это)

    могу объяснить почему, есть еще такие компоненты как dbExpress и у них есть "фича" параметры соединения (TSQLConnection.Params), если в них выставить параметр ServerCharSet=utf8 то он САМ конвертирует параметры в Utf8, не задевая остального (т.е. это не то же самое, что указать параметр соединения в строке подключения ADO, который в этом случае считает что весь текст запроса и параметры будут приходить в utf8), с ним этот драйвер работает хорошо, т.к. он у себя также по разному обрабатывает.
    т.е. есть разница, конфликт интересов, одно делается внутри компонента, другое внутри драйвера, и что не сделай кто то "пострадает" (ADO vs dbExpress), именно поэтому такая путаница в mysql-ных драйверах, пытаются угодить всем.
    вот. причину я понимаю, что делать тоже (нормальный путь - менять драйвер, кривой - подгонять свою прогу под работу драйвера, т.е делать самому перекодировки).
    не понимаю я одного, в [2]  ты пишешь о разнице при работе с одной строкой конекта (одним коннектором) при выполнении инсерта с параметром через ADOQuery и ADOCommand (ну так я понял), а вот этого уже не может быть... т.к. одно использует другое, и никаких особых действий при передаче параметров из одного в другое не делает.
  • aleks-ran © (08.08.09 13:56) [9]
    Давайте более подробно (не значащие строки все-таки опущу)
    На форме ADOConnection1, ADOQuery1, ADOCommand1, DBGrid1
    у ADOQuery1.SQL.Text всегда 'SELECT * FROM Clients'
    1 Вариант
     
    ADOConnection1.ConnectionString:='Provider=MSDASQL.1;Persist Security Info=False;Data Source=MySQLSource1';
     ADOQuery1.Open

    - все замечательно, в гриде все отображается правильно
     
     метод A:
     
    ADOCommand1.CommandText:='UPDATE Clients SET FirstName=''Иванов''';
     ADOCommand1.Execute;
     ADOQuery1.Close;
     ADOQuery1.Open;

    - все замечательно, в гриде все отображается правильно
     
     метод B:
     
    ADOCommand1.CommandText:='UPDATE Clients SET FirstName=:FN';
     ADOCommand1.Parameters.ParamValues['FN']:='Иванов'
     ADOCommand1.Execute;
     ADOQuery1.Close;
     ADOQuery1.Open;

    - все плохо, в гриде все отображается неправильно, в БД данные заносятся неправильно (смотрел в DBForge);
     если
       ADOCommand1.Parameters.ParamValues['FN']:=AnsiToUtf8('Иванов'); то крякозябры меняются и их количество удваивается (1байт - 2байта)
       
    2 Вариант
     Исправить ситуацию (ДЛЯ ЗАПРОСОВ НА ИЗМЕНЕНИЕ) можно только если:
     
    ADOConnection1.ConnectionString:='Provider=MSDASQL.1;Persist Security Info=False;Data Source=KlaesODBCAdministrator;Extended Properties=\"charset=utf8\"';


     И Затем
    ADOCommand1.Parameters.ParamValues['FN']:=AnsiToUtf8('Иванов');


     
    После ADOCommand1.Execute данные в БД заносятся ПРАВИЛЬНО!!!  (опять же смотрель в DBForge)
    НО ...
    При попытке открыть ADOQuery1.Open - в гриде КАША!!! (потому как в подключении Extended Properties="charset=utf8")
    Т.е. при работе с параметрами - единственный выход для ADOQuery1 один коннекшн либо строка подключения, а для ADOCommand1 - другая
    Я конечно программист слабый, но почему то кажется что это неправильно, держать два коннекшена, потому как при одном имеем проблему
    "туда дуй, оттуда ..." либо наоборот
    И то что происходит с запросами с параметрами, по моему, ошибка драйвера. (У ODBC_connector_3_51 такой проблемы нет вообще, отослал на
    сервер SET NAMES cp1251 и порядок)
    Дайте совет, куда бежать, долбиться с 5.1 (может все-таки чего-то делаю не правильно) или вернуться на 3.51

    С 3.51 спрыгнул только потому, что он при работе с ADOStoredProc, ADOCommand(в режиме CommandType=cmdStoredProc) при попытке выполнения
    на сервер отсылается почему-то {Call MyProc(param1, param2,...)} и эти скобки все ломают (Правда это не бог весть какая проблема :)  ).
    А в 5.1 поймал вышеописанную проблему

    Очень интересно, почему такое поведение? (Кривые руки или драйвер)
  • sniknik © (08.08.09 15:47) [10]
    > Очень интересно, почему такое поведение? (Кривые руки или драйвер)
    и то и другое, я уже написал, что этот драйвер по разному принимает текст запроса и текст текст параметров, почему так (объективные причины есть т.к. раньше они под кого то подстраивались) неважно. но это можно считать "кривизной".
    а руки (или скорее голова) кривые потому что не можешь разобраться и мечешься с драйвера на драйвер (3.51 это не старая версия, это параллельная) вместо этого.

    ладно, не буду больше теории, просто меняй в
    1 Вариант
    метод B:
    строчку
    ADOCommand1.Parameters.ParamValues['FN']:='Иванов'


    на
    ADOCommand1.Parameters.ParamByName('FN')..DataType:= ftWideString;
    ADOCommand1.Parameters.ParamByName('FN').Value:= 'Иванов';

    (проверил. он оказывается не в utf8 в противовес cp1251 запроса, а в юникоде, но все одно не сходится)

    > С 3.51 спрыгнул только потому, что он при работе с ADOStoredProc
    а надо было избавиться от ADOStoredProc. т.к. он от другой идеологии (BDE), вместе с ADOQuery, и если используется (самое ужасное) от ADOTable.
  • sniknik © (08.08.09 15:53) [11]
    > что этот драйвер по разному принимает текст запроса и текст текст параметров
    оп ля... чего то я тоже не подумал, а ведь комманттекст тоже вайдстринг и значит тоже строка конвертируется при присвоении... т.е. драйвер работает одинаково для обоих... похоже из списка "кривых" вещей можно исключить... остается одно. :)
  • aleks-ran © (10.08.09 10:30) [12]

    > sniknik ©

    Большое спасибо за помощь.
    >нормальный путь - менять драйвер, кривой - подгонять свою прогу под работу драйвера, т.е делать самому перекодировки)
    Т.е., насколько я понял, вернуться на 3.51 и не париться.
    Еще раз спасибо
  • Anatoly Podgoretsky © (10.08.09 11:08) [13]

    > ADOCommand1.Parameters.ParamByName('FN')..DataType:= ftWideString;
    >
    > ADOCommand1.Parameters.ParamByName('FN').Value:= 'Иванов';
    >
    > (проверил. он оказывается не в utf8 в противовес cp1251
    > запроса, а в юникоде, но все одно не сходится)

    На Д6 проверял или выше?
  • sniknik © (10.08.09 12:10) [14]
    > Т.е., насколько я понял, вернуться на 3.51 и не париться.
    читай внимательнее [10], после самостоятельной проверки все поменялось...
    5й тоже работает..., только не знаю как себя помню как Д6 с вайд стринг поведет... если также как D7, то должно быть все ок.
  • Anatoly Podgoretsky © (10.08.09 13:30) [15]
    > sniknik  (10.08.2009 12:10:14)  [14]

    Увы не так, это было причиной моего перехода с Д5 сначала на Д6, потом на Д7 и потом на Д2006, последнее не из-за ошибок с ftWideString, но из-за WideString. Поэтому минимальной версией можно считать Д7
    При том основная проблема с параметрами, а не полями.
  • aleks-ran © (10.08.09 13:42) [16]
    на основе поста [10]: плохо ведет, при
    ADOConnection1.ConnectionString:='Provider=MSDASQL.1;Persist Security Info=False;Data Source=MySQLSource1';

    вставка крякозябров
    при
    ADOConnection1.ConnectionString:='Provider=MSDASQL.1;Persist Security Info=False;Data Source=MySQLSource1';Extended Properties="charset=utf8"';


    сообщение об ошибке

    [MySQL][ODBC 5.1 Driver][mysqld-5.1.34-community]Incorrect string value: '\xD1\xE0\xF4\xE8\xED' for column 'FIO' at row 1.
  • sniknik © (10.08.09 15:24) [17]
    > на основе поста [10]: плохо ведет
    ну тогда что то менять да придется, либо драйвер либо дельфи...

    и кстати если еще не надоело проверь с другой кодировкой в строке, может понимает, напиши например
    "charset=ср1251" или charset="unicode", для первого в принципе (если поймет)  не нужно будет тип вайдстринг указывать, а второе может ошибку уберет.
    может и подберешm рабочую комбинацию когда запрос/выдаваемые данные одинаково с параметрами будет восприниматься.
  • aleks-ran © (11.08.09 10:33) [18]

    > sniknik ©

    с charset=ср1251 вообще не работает, пишет что-то вроде:
    "драйвер или поставщик данных вернул состояние E_FAIL",
    разные кодировки пробовал, на каждой что-то, но неправильно, в общем

    > ну тогда что то менять да придется, либо драйвер либо дельфи.
    > ..

    вернулся на 3.51
    Спасибо всем за обсуждение темы.
 
Конференция "Базы" » Параметры и mysql-connector-odbc-5.1.5 [D6, MySQL]
Есть новые Нет новых   [134474   +35][b:0][p:0.002]