-
Уважаемые мастера, подскажите решение следующей проблемы: При выполнении запроса 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
-
> в кодировке UTF8 попробуй сам преобразовать значение присваиваемое параметру в UTF8...
> Знаю что через mysql-connector-odbc-3.51 все работает, но нужно именно через 5.1 там главное не версия, главное что какие то драйвера "русифицированы", помню тоже подбирал подходящие. подошли те которые рекомендовали на mysql.ru.
-
Я тут немного разобрался, как выйти из положения, но ясности это не добавило. :) 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 - другая , с явным указанием кодировки. Почему? Как-то несимметричненько :)
-
что то что другое неправильно, должен быть отдельный "коннектор". а строка у компонента... можно даже не рассматривать. вот сделай коннектор, подключи к нему оба компонента, потом и смотри разницу.
-
А я сразу так и делал. Смотри первоначальный вопрос. Потом было просто лень бросать на форму второй ADOConnection Впрочем, с ним ситуация такая же как в [2]
-
> Впрочем, с ним ситуация такая же как в [2] т.е. оба "смотрят" в одно соединение, одинаковый запрос, одинаковый параметр (тип параметра если установлен), одинаковое значение задается, и у одного компонента пишется по русски, у другого нет? верится с трудом, тем более ADOQuery через такой же ADOCommand запросы выполняет, что и на палитре.
-
Вы не поняли, смотрите первоначальный вопрос. Все компоненты смотрели в один и тот же 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; но если с этой строкой подключения сделать запрос на выборку то тогда уже с ним в гриде будут крякозябры
-
Виноват, Parameters.ParamValues['FN']:=AnsiToUtf8(Edit1.Text);
-
> Вы не поняли да нет, все я понял, понял, что разных вариантах разные результаты, и общая кодировка не совпадает с кодировкой параметров... (если посмотришь внимательно я еще в [1] советовал рабочий вариант с самостоятельной перекодировкой, т.к. подозревал именно это)
могу объяснить почему, есть еще такие компоненты как dbExpress и у них есть "фича" параметры соединения (TSQLConnection.Params), если в них выставить параметр ServerCharSet=utf8 то он САМ конвертирует параметры в Utf8, не задевая остального (т.е. это не то же самое, что указать параметр соединения в строке подключения ADO, который в этом случае считает что весь текст запроса и параметры будут приходить в utf8), с ним этот драйвер работает хорошо, т.к. он у себя также по разному обрабатывает. т.е. есть разница, конфликт интересов, одно делается внутри компонента, другое внутри драйвера, и что не сделай кто то "пострадает" (ADO vs dbExpress), именно поэтому такая путаница в mysql-ных драйверах, пытаются угодить всем. вот. причину я понимаю, что делать тоже (нормальный путь - менять драйвер, кривой - подгонять свою прогу под работу драйвера, т.е делать самому перекодировки). не понимаю я одного, в [2] ты пишешь о разнице при работе с одной строкой конекта (одним коннектором) при выполнении инсерта с параметром через ADOQuery и ADOCommand (ну так я понял), а вот этого уже не может быть... т.к. одно использует другое, и никаких особых действий при передаче параметров из одного в другое не делает.
-
Давайте более подробно (не значащие строки все-таки опущу) На форме 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 поймал вышеописанную проблему Очень интересно, почему такое поведение? (Кривые руки или драйвер)
-
> Очень интересно, почему такое поведение? (Кривые руки или драйвер) и то и другое, я уже написал, что этот драйвер по разному принимает текст запроса и текст текст параметров, почему так (объективные причины есть т.к. раньше они под кого то подстраивались) неважно. но это можно считать "кривизной". а руки (или скорее голова) кривые потому что не можешь разобраться и мечешься с драйвера на драйвер (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 ©
Большое спасибо за помощь. >нормальный путь - менять драйвер, кривой - подгонять свою прогу под работу драйвера, т.е делать самому перекодировки) Т.е., насколько я понял, вернуться на 3.51 и не париться. Еще раз спасибо
-
> ADOCommand1.Parameters.ParamByName('FN')..DataType:= ftWideString; > > ADOCommand1.Parameters.ParamByName('FN').Value:= 'Иванов'; > > (проверил. он оказывается не в utf8 в противовес cp1251 > запроса, а в юникоде, но все одно не сходится)
На Д6 проверял или выше?
-
> Т.е., насколько я понял, вернуться на 3.51 и не париться. читай внимательнее [10], после самостоятельной проверки все поменялось... 5й тоже работает..., только не знаю как себя помню как Д6 с вайд стринг поведет... если также как D7, то должно быть все ок.
-
> sniknik (10.08.2009 12:10:14) [14]
Увы не так, это было причиной моего перехода с Д5 сначала на Д6, потом на Д7 и потом на Д2006, последнее не из-за ошибок с ftWideString, но из-за WideString. Поэтому минимальной версией можно считать Д7 При том основная проблема с параметрами, а не полями.
-
на основе поста [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.
-
> на основе поста [10]: плохо ведет ну тогда что то менять да придется, либо драйвер либо дельфи...
и кстати если еще не надоело проверь с другой кодировкой в строке, может понимает, напиши например "charset=ср1251" или charset="unicode", для первого в принципе (если поймет) не нужно будет тип вайдстринг указывать, а второе может ошибку уберет. может и подберешm рабочую комбинацию когда запрос/выдаваемые данные одинаково с параметрами будет восприниматься.
-
> sniknik ©
с charset=ср1251 вообще не работает, пишет что-то вроде: "драйвер или поставщик данных вернул состояние E_FAIL", разные кодировки пробовал, на каждой что-то, но неправильно, в общем
> ну тогда что то менять да придется, либо драйвер либо дельфи. > ..
вернулся на 3.51 Спасибо всем за обсуждение темы.
|