Текущий архив: 2004.04.18;
Скачать: CL | DM;
ВнизПроблема Юникода в запросе SQL Найти похожие ветки
← →
Rauf © (2004-03-09 13:51) [0]Была проблема. Не мог использовать Юникод символы с элементами управления в Дельфи. Все решил скачал Tnt библиотеку и все ОК. Теперь другая проблема.
Разместил на форме элемент TTntEdit. И при щелчке на кнопке выполняется следующее
ADODataset.CommandText := "select * from main where Name = """ + TntEdit.Text + """";
ADODataset.Open();
if ADODataset.IsEmpty() then ShowMessage( "empty" );
ADODataset.Close();
При использовании Английских букв и русских (установлен русский стандарт распознавания неЮникода текста), все проходит на Ура. Но как только пишу Юникод текст (на другом языке) в TntEdit, то возникает сообщение Empty.
Использую Delphi 7, БД - MS ACCESS.
Если кто сталкивался с проблемой такой, то помогите чем сможете.
P.S. Причем если проверять все вручную, через условие
if WideString( ADODataSet.FieldByName( "Name" ).AsVariant ) = TntEdit.Text,
то все нормально проходит!!!
← →
sniknik © (2004-03-09 14:03) [1]не сталкивался (не нужно было) но тут явно проблема в том что сам ADODataset.CommandText не юникодный.
попробуй строку через параметр передавать.
← →
Rauf © (2004-03-09 17:10) [2]Но ведь тип ADODataSet.CommandText WideString. Почему же он тогда не Юникодный???
← →
sniknik © (2004-03-09 18:39) [3]а весь VCL считается не поддерживает юникод и чем он лутше к примеру визуального TLabel.TCaption который типа AnsiString что одно и тоже "The WideString type..... it is similar to AnsiString"
лутше скажи через параметр правильно передается?
← →
Rauf © (2004-03-09 23:02) [4]Я новенький в этом деле, и этого пока не пробовал, ну попробую, постараюсь попробовать!!!
← →
BPK (2004-03-10 22:12) [5]А если "select * from main where Name = " оформить как константу типа WideString?
← →
Rauf © (2004-03-11 01:21) [6]Дело в том, что если я потом показываю CommandText через
MessageBoxW (Юникод версия т.е.), то он показывает запрос нормально, в юникод символах!!!
← →
Rauf © (2004-03-12 01:24) [7]Вот попробовал через параметры сделать!!!
Задал SQL запрос в CommandText TADODataset"a
select * from Table1 where Name = :Name
Для появившегося в списке параметров параметра Name установил следующие свойства
Attributes - все False
Datatype - ftWideString
Direction - ftInput
NumericScale, Precision - 0
Size - -1
Value.Type = OleStr
Вот что делаю далее
a_ds.Parameters.ParamValues[ "Name" ] := e1.Text;
a_ds.Open();
if a_ds.IsEmpty()
then ShowMessage( "Empty" );
a_ds.Close();
Опять Empty. Посмотрите, может я что не так делаю???
P.S. С неЮникод символами опять все проходит, а с Юникод мммм, ну в общем вы знаете!!!
← →
sniknik © (2004-03-12 10:54) [8]к сожалению сам проверить не могу, надо компаненты ставить...
придется пока тебе самому проверять,
вот это (то что работает)
if WideString(ADODataSet.FieldByName( "Name" ).AsVariant ) = TntEdit.Text ,
это же получается сначала преобразование строки в юникод а после сравнение, а строка из рекордсета может быть и не юникодной...
в запросе ты сравниваеш без преобразований
попробуй так
select * from Table1 where StrConv(Name, 64) = :Name
потом, возможно в сравнении по "строковым правилам" включаются разные факторы (ну делает жеон преобразования так что а=А становится, а как это на второй символ в юникоде влияет ? хз.) попробуй бинарное сравнение
select * from Table1 where StrComp(Name, :Name, 0) = 0
в конце концов проверь а действительно там у тебя юникод? в базе (по примеру с преобразованием необязательно)
подключи полученый рекордсет к стандартному гриду, теоретически в нем далжна быть легко узнаваемая абракадабра. :)
← →
Rauf © (2004-03-12 14:00) [9]Так, а теперь, если вас не затруднит, объясните, ведь говорят, что TADODataset наследует в себе свойства TADOTable и TADOQuery. Так к чему это я. Я TADOQuery попробовал. Добавил запрос,
select * from Table1 where Name = :Name
В TADOQuery запихиваю в параметр Name значение, ну короче как в TADODataset. Но вот в чем проблема. В TADOQuery все пашет, круто, а в TADODataset нет. Так как же он наследует свойства TADOTable и TADOQuery???
← →
sniknik © (2004-03-12 14:16) [10]ну если быть точным то все три TADODataset, TADOTable и TADOQuery наследники от TCustomADODataSet просто у TADODataset обкрыта большая часть методов родителя а у TADOTable и TADOQuery частично, добавлено только то что "приближает" их к BDE-шным TTable и TQuery они и сделаны для "облегчения перехода" (это в хелпе гдето читал).
почему там работает а там нет, загадка. возможно разгадка в том каким образом попадает текст запроса из добавленного списка (SQL: TStrings) в CommandText обьекта (может там где дополнительные преобразования), хотя нет. параметры же... в общеи нужно смотреть. (видимо придется всетаки TNT себе поставить, но это только дома)
← →
Rauf © (2004-03-12 14:21) [11]Ставь, к проблемам это не должно привести!!!
Очень интересно, значит я так понимаю, проблема не в самом запросе и не в MSACCESS"е. А в компоненте. Или нет ...???
← →
sniknik © (2004-03-12 14:52) [12]> не в самом запросе и не в MSACCESS"е. А в компоненте. Или нет ...???
не понимаю в чем разница, и пока не проверю вряд ли скажу,
сам запрос обрабатывается не в компоненте, параметры одним и темже кодом представлены, запрос единственное, но тоже какая разница (в явном виде же там юникода не присутствует) а то что он вначале с FSQL сохраняется то какая разница, дальше то все одно присваивается к CommandText который у всех общий.
procedure TADOQuery.QueryChanged(Sender: TObject);
begin
if not (csLoading in ComponentState) then Close;
CommandText := FSQL.Text;
end;
он в TADOQuery даже не переопределен, вызывается метод от TCustomADODataSet (SetCommandText).
в общем нет гадать не буду, надо проверять (пока мне проще предположить что это ты гдето ошибся, скажем не ту строку ищеш что в первом случае... и.т.д.).
← →
Rauf © (2004-03-12 17:15) [13]Тогда, если не возражаешь, я тебе пришлю проект с БД и там будет использование обоих компонентов, ну а ты сам проверешь, что надо, что бы лишней работы не проделывать!!!
Если ОК, то я на мыло могу прислать.
Все равно спасибо за внимание.
← →
sniknik © (2004-03-12 17:45) [14]Ok.
не за что, именно изза таких проблем в основном и хожу на форум. (новое), одно и тоже надоедает.
смотреть буду скорее всего в суботу воскресенье.
← →
sniknik © (2004-03-13 12:24) [15]странность с разным поведением, ADODataSet и ADOQuery пока не выяснил,
но вот некоторые "глюки" заметил первое в базе - таблице поле name
(то что сравнивается) стоит сжатие юникод - да, это значит что частично
в базе не юникодные поля, все в с основной и дополнительной раскладки
(ангийский, руский, что с 0 начинаются) будут сжаты в простую строку самим
движком бызы.
это обьясняет почему кроме двух значений (именно ини остались в юникод),
остальные ишутся нормально и там и там.
потом компоненты ни причем явно, достаточно указать строку подключения не
через ODBC а OLEDB Jet
Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\test_db_unicode\test_db_unicode.mdb;Persist Security Info=False
и поиск по юникоду опять востанавливается для обоих компонент.
(вот! пользуйтесь новыми а не устаревшими технологиями :)
т.е. чтото с ODBC, какието параметры передаются в случае с одним компонентом
и не задаются в другом.
пока что нашол единственное, в ADOQuery изменяется CommandTextAlias:=
"SQL"; от по умолчанию "CommandText" но установка тогоже у датасета
TMyADOCommand(TMyADODataSet(a_ds).Command).CommandTextAlias:= "SQL";
ничего не дала... возможно нужно при создании (чтото от него меняет) а не
после, остальное (присвоение параметра, и открытие) идет на один и тот же код.
в общем в чем разница так и не понятно, пока надеюсь.
← →
Ray Adams (2004-03-13 15:59) [16]Видать ты Азербайджанский пытаешся юзать, а он не будет пахать так как пока не поддерживается нормальным образом.
← →
sniknik © (2004-03-13 18:15) [17]Ray Adams (13.03.04 15:59) [16]
естественно про то и вопрос, и не обязательнно только Азербайджанский можно и Угундский ... и т.д.
более менее разобрался, не совсем конечно но тем не менее
разница в параметрах в том как задается тип, хотя хоть убей не понимаю почему,
один и тот же код отрабатывает...
в общем если в TADOQuery тип параметра (задаваемого в дезигн тайме!) ftWideString
и так и остается то для TADODataSet он на момент выполнение равен ftUnknown
хотя также как в с квери в дезигн тайме задается ftWideString.
т.е. еслм для датасета задавать параметр не
a_ds.Parameters.ParamValues[ "name" ] := Name.Text;
а
a_ds.Parameters[0].Value:= Name.Text;
a_ds.Parameters[0].DataType:= ftWideString;
то тоже проходит, и находит.
а вот если использовать компоненты создаваемяе в рантайм, (для Query)
var Quer: TADOQuery;
begin
Quer:= TADOQuery.Create(Self);
try
Quer.Connection:= a_c;
Quer.SQL.Add("select * from main where name = :name");
Quer.Parameters.ParamValues["name"]:= Name.Text;
Quer.Open;
Label1.Caption:= IntToStr(Quer.RecordCount);
TntLabel1.Caption:= Quer.Parameters[0].Value;
if Quer.IsEmpty then ShowMessage("Empty")
else MessageBoxW(Handle, PWideChar(WideString(Quer.FieldByName( "name" ).AsVariant)), PWideChar(WideString(Нашел)), MB_OK );
Quer.Close;
finally
Quer.Free;
end;
то поведение обоих одинаково, без явного указания типа как выше не ищут оба, ну это и понятно
в обоих ftUnknown получается.
почему из дезайн тип параметра в в одном случае не прекочевывает в рантайм х.з.
(да и выяснять уже неохота, по сути уже понятно)
да, если пользоватся строкой с OLEDB Jet все работает т.к. он может определять реальный тип при ftUnknown сам.
(в этом случае по крайне мере)
← →
Ray Adams (2004-03-18 20:09) [18]Это проблема именно базы и системы работы с ней, к примеру я такое уже увидел на InterBase никак не пихали аз unicode, матерился сервер на неподдерживаемую кодовую страницу
← →
sniknik © (2004-03-18 20:37) [19]в InterBase есть чтото типа COLLATE/COLLATION (отвечающее за национальный язык), и кстати их (интербезы) тоже по версиям надо смотреть, старые наверняка нет(но чего ожидать если юникод был позже придуман).
ты б еще с dBase III сравнил. ;о)
но тут конкретно задана база - access, он с 2000го (а может и раньше) поддерживает юникод. о чем есть соответствующие записи в хелпе.
и кстати зачем спориш? есть как минимум уже 2 человека у которых это работает - Rauf и я.
Страницы: 1 вся ветка
Текущий архив: 2004.04.18;
Скачать: CL | DM;
Память: 0.51 MB
Время: 0.037 c