Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2006.01.15;
Скачать: [xml.tar.bz2];

Вниз

ADOQuery + ClientDataSet. Ошибка при пустом параметре   Найти похожие ветки 

 
Vlad ©   (2005-11-15 17:54) [0]

БД - MS-SQL
В ADOQuery пишу простейший запрос:
select * from MyTable where MyStringField = :param
Параметру задаю тип String, нужную длину и т.п.
в коде программы:
AdoQuery.Parameters[0].Value := ""; // задаю пустую строку
AdoQuery.Open;

Все работает как надо.

Теперь беру ClientDataSet и через провайдера подключаю его к моему ADOQuery. У ClientDataSet так же прописываю параметр и задаю ему тип String и нужную длину.
в коде программы пишу:

ClientDataSet.Params[0].Value := "";
ClientDataSet.Open;

Так вот, если параметру присвоить пустое значение, то на Open вываливается exception: "The text, ntext ot image data can not be compared or sorted, except wher using IS NULL or LIKE operator".
Если непустое - то все ОК.
Смотрю профайлером, какой запрос посылается на сервер.
Профайлер говорит что тип моего параметра почему-то "text", значение - ""
а в случае непустого параметра - тип varchar, как и должно быть.

Так же, если использовать ADOQuery, без всяких ClientDataSet-ов, то пустой параметр тоже проходит нормально, и подставляется как varchar

Вобщем, понятно что кто-то (толи ClientDataSet, толи DataSetProvider) неправильно интерпретирует тип параметра, в случае, если ему присвоить "". Но непонятно как это побороть.

Приходила в голову идея в sql запросе явно преобразовывать параметр к varchar, но это если не докопаюсь до истины...

Поделитесь, если у кого нибудь возникнут какие-то мысли по поводу данной проблемы.
Спасибо.


 
Ega23 ©   (2005-11-15 18:06) [1]

Попробуй у строки длину поставь. 50, например.


 
Vlad ©   (2005-11-15 18:09) [2]


> Ega23 ©   (15.11.05 18:06) [1]
> Попробуй у строки длину поставь. 50, например.

В смысле у параметра? Сколько не ставь, хоть 50 хоть 150 - бесполезно :-(


 
Ega23 ©   (2005-11-15 18:13) [3]


> В смысле у параметра? Сколько не ставь, хоть 50 хоть 150
> - бесполезно :-(


А зачем ты, кстати, ClientDataSet"у параметр прописываешь?


 
Vlad ©   (2005-11-15 18:19) [4]


> Ega23 ©   (15.11.05 18:13) [3]

Если быть точнее, руками я его не прописываю, а делаю Fetch params в дизайн-тайме. При этом он сам у себя прописывает параметр, соответствующий параметру у ADOQuery.
Я просто контролирую чтобы тип и размер совпадал с тем, который у ADOQuery (бывает, иногда не совпадает)


 
ivb2001   (2005-11-15 20:57) [5]

Для SQL паскакалевские двойные кавырки - пустой звук. Я с этим в InterBase напарился вдоволь. Попробуйте чиста канкретно присвоить NIL(вот только забыл как это правильно будет EmptyVar то ли VarEmpty ибо Parms[].value имеет тип Variant) Вобщем идея, думается, понятна


 
Vlad ©   (2005-11-15 21:04) [6]


> ivb2001   (15.11.05 20:57) [5]


> Попробуйте чиста канкретно присвоить NIL

Вероятно, имелось ввиду null?
Ну да, можно и так, только в результате и в sql запрос подставится null, а мне нужно подставить туда пустую строку :-)
И еще, не понимаю как связаны "паскалевские" кавычки и SQL ? :-)


 
sniknik ©   (2005-11-15 21:48) [7]

> select * from MyTable where MyStringField = :param
....
> ClientDataSet.Params[0].Value := "";
> ClientDataSet.Open;

> Так вот, если параметру присвоить пустое значение, ...
т.е. нужно сравнить с пустой строкой? попробуй так  
ClientDataSet.Params[0].Value := #32;


 
Desdechado ©   (2005-11-15 22:49) [8]

может, стоит присваивать не Value, а AsString ?


 
Johnmen ©   (2005-11-15 23:39) [9]

Да-да, Desdechado © похоже прав.
Params.ParamByName("xxx").AsString

>sniknik ©   (15.11.05 21:48) [7]
>ClientDataSet.Params[0].Value := #32;

Это же пробел...:)


 
sniknik ©   (2005-11-15 23:56) [10]

> Это же пробел...:)
а то я не знаю. просто напиши здесь пробел в скобочках " " практически не отличается от "", а так видиш заметно.


 
Vlad ©   (2005-11-16 08:29) [11]


> Desdechado ©   (15.11.05 22:49) [8]
> может, стоит присваивать не Value, а AsString ?

Нет, не в этом дело. И Value и AsString дают одинаковый результат (ошибку), если присваивать параметру пустую строку.
Причем, если работать напрямую с ADOQuery, то с его параметром проходит нормально хоть пустой хоть непустой параметр.
А вот ClientDataSet-овскому параметру присвоить пустое значение, то получается такая вот фигня... Провайдер почему-то решил, что пустая строка имеет тип text, а не varchar, и в запрос подставляет ее как тип text, из-за чего видимо и вылазит ошибка.


> sniknik ©   (15.11.05 23:56) [10]

С пробелом-то все работает. Но это не пустая строка :-)


 
sniknik ©   (2005-11-16 08:58) [12]

> С пробелом-то все работает. Но это не пустая строка :-)
а ты всетаки попробуй.


 
Vlad ©   (2005-11-16 09:04) [13]

Я кстати пытался посмотреть как все-таки провайдер формирует sql запрос, но исходников нету. Видимо все это зашито в midaslib, а pas-файла нету, только dcu


 
Vlad ©   (2005-11-16 09:05) [14]


> sniknik ©   (16.11.05 08:58) [12]
> > С пробелом-то все работает. Но это не пустая строка :-
> )
> а ты всетаки попробуй.

Пробовал. Запрос формируется нормально, параметр имеет тип varchar как нужно. Ошибок нет. Но и данных нет :-)


 
Johnmen ©   (2005-11-16 09:32) [15]


> Vlad ©   (15.11.05 17:54)  
> БД - MS-SQL
> В ADOQuery пишу простейший запрос:
> select * from MyTable where MyStringField = :param


А если так
select * from MyTable where MyStringField =CAST(:param AS VARCHAR(X))


 
Vlad ©   (2005-11-16 09:36) [16]


> Johnmen ©   (16.11.05 09:32) [15]

Угу. Это первое, что пришло мне в голову. Так работает.
Непонятно почему без этого не работает :-)


 
Johnmen ©   (2005-11-16 09:44) [17]


> Vlad ©   (16.11.05 09:36) [16]
> Непонятно почему без этого не работает :-)


Ну это то понятно
>"The text, ntext ot image data can not be compared or sorted, except wher
>using IS NULL or LIKE operator".

Непонятно, почему это...
:)

Кстати, а какой тип в дизайне у параметра CDS?


 
Vlad ©   (2005-11-16 09:57) [18]


> Кстати, а какой тип в дизайне у параметра CDS?

ftString

а вот что выдает профайлер, если присвоить пустое значение параметру:

exec sp_executesql N"select * from personalaccount where personalaccount_id = @P1", N"@P1 text", ""
(Возникает вышеуказанная ошибка)

и вот что при непустом:

exec sp_executesql N"select * from personalaccount where personalaccount_id = @P1", N"@P1 varchar(4)", "AFKN"
(Ошибки нет)

в обоих случаях в CDS тип параметра ftString. Менял только строчку кода
в первом случае писал
ClientDataSet.Params[0].AsString := "";
во втором
ClientDataSet.Params[0].AsString := "AFKN";


 
Johnmen ©   (2005-11-16 10:13) [19]

Посмотри ещё
Params[x].Text в рантайме
и
Params -> Value -> Type в дизайне


 
Vlad ©   (2005-11-16 10:30) [20]


> Params[x].Text в рантайме

пустая строка


> Params -> Value -> Type в дизайне

string


 
Johnmen ©   (2005-11-16 11:52) [21]

Я, кажить, понял в чём дело...
Глянь в DBClient.pas реализацию TCustomClientDataSet.SetOptionalParam
Очень интересно со строковым типом...:)


 
Vlad ©   (2005-11-16 12:12) [22]


> Johnmen ©   (16.11.05 11:52) [21]

Ты про OleStr, там где происходит попытка преобразования к TSQLTimeStamp?
И, кстати, а причем тут опциональные параметры, я ж их не задаю...


 
Vlad ©   (2005-11-16 12:45) [23]


> Johnmen ©   (16.11.05 11:52) [21]

Я кажется понял, что ты имел ввиду...
ParamType := ParamTypeMap[VarType(Value) and varTypeMask];
для того чтобы получилось dsfldZSTRING нужно чтобы параметр был типа OleStr
кстати, если VarType(Value) вернет varString получится полная фигня :-)

Но опять же встает вопрос - как опциональные параметры применить к моей ситуации? :-)


 
Johnmen ©   (2005-11-16 13:22) [24]

Что-то ДельфиМастера подглюкивают...:)
Писал пост, он ушёл в аут. Повторяться лень.

>Vlad ©   (16.11.05 12:45) [23]

Я имел в в виду строки
ParamLen := Length(S) + 1;
и
ParamType := ParamType shl dsSizeBitsLen or ParamLen;

Опциональные параметры м.б. и непричём. Важно, что какие-то манипуляции с типом происходят на основании данных параметра.


 
Vlad ©   (2005-11-16 13:35) [25]


> Johnmen ©   (16.11.05 13:22) [24]



> ParamLen := Length(S) + 1;

ну здесь то все понятно: устанавливают длину параметра равной длине переменной + 1 (видимо для завершающего #0)


> ParamType := ParamType shl dsSizeBitsLen or ParamLen;

Вот тут не очень понятно... С какой-то целью меняется тип параметра в завис. от его размера

но фишка в другом: TCustomClientDataSet.SetOptionalParam не выполняется вообще (дебаггером проверял).
А вот то место где считываются параметры (которые TParams, а не опциональные) и где они подставляются в запрос - я так и не нашел :-(


 
Johnmen ©   (2005-11-16 13:49) [26]

>Vlad ©   (16.11.05 13:35) [25]

Я бы вывел в Watches тип интересующего параметра и пошёл бы дебаггером, чтобы найти то место, где тип переопределяется...


 
Vlad ©   (2005-11-16 15:04) [27]


> Johnmen ©   (16.11.05 13:49) [26]

Прошелся ради интереса. Тип нигде не переопределяется.
DataSetProvider считывает параметры у ClientDataSet и подставляет их в ADOQuery (подставляет правильно, я проверил). Больше никаких манипуляций с параметрами не проводилось.
Затем провайдер открывает ADOQuery, и там, вглубине метода Open возникает исключение в строчке Recordset.Open (вызов метода COM-объекта).
При всем при этом никаких изменений в параметрах не происходило вплоть до возникновения exception-a. Тип и значения были верными.


 
Johnmen ©   (2005-11-16 15:52) [28]

>Vlad ©   (16.11.05 15:04) [27]

...
Ещё есть смутные идеи... Но озвучивать не буду :)

PS
попробуй
ClientDataSet.Params[0].Value := #0;


 
Vlad ©   (2005-11-16 16:37) [29]


> ClientDataSet.Params[0].Value := #0;

Так сработало :-)
Но так придется каждый раз в программе производить подмену пустой строки на #0., ну впринципе тоже выход :-)



Страницы: 1 вся ветка

Форум: "Базы";
Текущий архив: 2006.01.15;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.52 MB
Время: 0.014 c
1-1134292864
-Andru-
2005-12-11 12:21
2006.01.15
Help! Help! Help!


9-1122904615
Novouralsk
2005-08-01 17:56
2006.01.15
Псевдо анимация


14-1134682783
аматор
2005-12-16 00:39
2006.01.15
компилятор на паскале


14-1134898418
Virgo_Style
2005-12-18 12:33
2006.01.15
аська и почта на мобильном


5-1121170155
mmms
2005-07-12 16:09
2006.01.15
Как переопределить свойство





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский