Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 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
3-1080047576
Aleksandr
2004-03-23 16:12
2004.04.18
Какой командой из триггера MS SQL можно запустить файл?


1-1080657541
Noway
2004-03-30 18:39
2004.04.18
задержка


3-1079688643
Romeo
2004-03-19 12:30
2004.04.18
Удаленный доступ к двум (и более) таблицам базы через DCOM


1-1080665105
ботинок
2004-03-30 20:45
2004.04.18
как в tabcontrole определить по какому из tabs-ов кликнули мышью?


6-1074854456
juiceman
2004-01-23 13:40
2004.04.18
what about Indy ?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский