![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Параметры и mysql-connector-odbc-5.1.5 [D6, MySQL]
aleks-ran © (2009-08-07 16:48:00)Уважаемые мастера, подскажите решение следующей проблемы:
При выполнении запроса
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
aleks-ran (2009-08-11 10:33:00) [1]
> sniknik ©
с charset=ср1251 вообще не работает, пишет что-то вроде:
"драйвер или поставщик данных вернул состояние E_FAIL",
разные кодировки пробовал, на каждой что-то, но неправильно, в общем
> ну тогда что то менять да придется, либо драйвер либо дельфи.
> ..
вернулся на 3.51
Спасибо всем за обсуждение темы.
sniknik (2009-08-10 15:24:00) [2]> на основе поста [10]: плохо ведет
ну тогда что то менять да придется, либо драйвер либо дельфи...
и кстати если еще не надоело проверь с другой кодировкой в строке, может понимает, напиши например
"charset=ср1251" или charset="unicode", для первого в принципе (если поймет) не нужно будет тип вайдстринг указывать, а второе может ошибку уберет.
может и подберешm рабочую комбинацию когда запрос/выдаваемые данные одинаково с параметрами будет восприниматься.
aleks-ran (2009-08-10 13:42:00) [3]на основе поста [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.
Anatoly Podgoretsky (2009-08-10 13:30:00) [4]> sniknik (10.08.2009 12:10:14) [14]
Увы не так, это было причиной моего перехода с Д5 сначала на Д6, потом на Д7 и потом на Д2006, последнее не из-за ошибок с ftWideString, но из-за WideString. Поэтому минимальной версией можно считать Д7
При том основная проблема с параметрами, а не полями.
sniknik (2009-08-10 12:10:00) [5]> Т.е., насколько я понял, вернуться на 3.51 и не париться.
читай внимательнее [10], после самостоятельной проверки все поменялось...
5й тоже работает..., только не знаю как себя помню как Д6 с вайд стринг поведет... если также как D7, то должно быть все ок.
Anatoly Podgoretsky (2009-08-10 11:08:00) [6]
> ADOCommand1.Parameters.ParamByName('FN')..DataType:= ftWideString;
>
> ADOCommand1.Parameters.ParamByName('FN').Value:= 'Иванов';
>
> (проверил. он оказывается не в utf8 в противовес cp1251
> запроса, а в юникоде, но все одно не сходится)
На Д6 проверял или выше?
aleks-ran (2009-08-10 10:30:00) [7]
> sniknik ©
Большое спасибо за помощь.
>нормальный путь - менять драйвер, кривой - подгонять свою прогу под работу драйвера, т.е делать самому перекодировки)
Т.е., насколько я понял, вернуться на 3.51 и не париться.
Еще раз спасибо
sniknik (2009-08-08 15:53:00) [8]> что этот драйвер по разному принимает текст запроса и текст текст параметров
оп ля... чего то я тоже не подумал, а ведь комманттекст тоже вайдстринг и значит тоже строка конвертируется при присвоении... т.е. драйвер работает одинаково для обоих... похоже из списка "кривых" вещей можно исключить... остается одно. :)
sniknik (2009-08-08 15:47:00) [9]> Очень интересно, почему такое поведение? (Кривые руки или драйвер)
и то и другое, я уже написал, что этот драйвер по разному принимает текст запроса и текст текст параметров, почему так (объективные причины есть т.к. раньше они под кого то подстраивались) неважно. но это можно считать "кривизной".
а руки (или скорее голова) кривые потому что не можешь разобраться и мечешься с драйвера на драйвер (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.
aleks-ran (2009-08-08 13:56:00) [10]Давайте более подробно (не значащие строки все-таки опущу)
На форме 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';- все плохо, в гриде все отображается неправильно, в БД данные заносятся неправильно (смотрел в DBForge);
ADOCommand1.Parameters.ParamValues['FN']:='Иванов'
ADOCommand1.Execute;
ADOQuery1.Close;
ADOQuery1.Open;
если
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 (2009-08-08 10:43:00) [11]> Вы не поняли
да нет, все я понял, понял, что разных вариантах разные результаты, и общая кодировка не совпадает с кодировкой параметров...
(если посмотришь внимательно я еще в [1] советовал рабочий вариант с самостоятельной перекодировкой, т.к. подозревал именно это)
могу объяснить почему, есть еще такие компоненты как dbExpress и у них есть "фича" параметры соединения (TSQLConnection.Params), если в них выставить параметр ServerCharSet=utf8 то он САМ конвертирует параметры в Utf8, не задевая остального (т.е. это не то же самое, что указать параметр соединения в строке подключения ADO, который в этом случае считает что весь текст запроса и параметры будут приходить в utf8), с ним этот драйвер работает хорошо, т.к. он у себя также по разному обрабатывает.
т.е. есть разница, конфликт интересов, одно делается внутри компонента, другое внутри драйвера, и что не сделай кто то "пострадает" (ADO vs dbExpress), именно поэтому такая путаница в mysql-ных драйверах, пытаются угодить всем.
вот. причину я понимаю, что делать тоже (нормальный путь - менять драйвер, кривой - подгонять свою прогу под работу драйвера, т.е делать самому перекодировки).
не понимаю я одного, в [2] ты пишешь о разнице при работе с одной строкой конекта (одним коннектором) при выполнении инсерта с параметром через ADOQuery и ADOCommand (ну так я понял), а вот этого уже не может быть... т.к. одно использует другое, и никаких особых действий при передаче параметров из одного в другое не делает.
aleks-ran (2009-08-08 00:07:00) [12]Виноват, Parameters.ParamValues['FN']:= AnsiToUtf8(Edit1.Text);
aleks-ran (2009-08-07 23:52:00) [13]Вы не поняли, смотрите первоначальный вопрос.
Все компоненты смотрели в один и тот же 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;
но если с этой строкой подключения сделать запрос на выборку то тогда уже с ним в гриде будут крякозябры
sniknik (2009-08-07 23:32:00) [14]> Впрочем, с ним ситуация такая же как в [2]
т.е. оба "смотрят" в одно соединение, одинаковый запрос, одинаковый параметр (тип параметра если установлен), одинаковое значение задается, и у одного компонента пишется по русски, у другого нет?
верится с трудом, тем более ADOQuery через такой же ADOCommand запросы выполняет, что и на палитре.
aleks-ran (2009-08-07 22:37:00) [15]А я сразу так и делал. Смотри первоначальный вопрос.
Потом было просто лень бросать на форму второй ADOConnection
Впрочем, с ним ситуация такая же как в [2]
sniknik (2009-08-07 21:42:00) [16]что то что другое неправильно, должен быть отдельный "коннектор". а строка у компонента... можно даже не рассматривать.
вот сделай коннектор, подключи к нему оба компонента, потом и смотри разницу.
aleks-ran (2009-08-07 21:27:00) [17]Я тут немного разобрался, как выйти из положения, но ясности это не добавило. :)
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 (2009-08-07 20:50:00) [18]> в кодировке UTF8
попробуй сам преобразовать значение присваиваемое параметру в UTF8...
> Знаю что через mysql-connector-odbc-3.51 все работает, но нужно именно через 5.1
там главное не версия, главное что какие то драйвера "русифицированы", помню тоже подбирал подходящие. подошли те которые рекомендовали на mysql.ru.