Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Вернуть результат из вычисляемого поля запроса [D7, IB6.x, FireBird]


Страницы:   1 2

Shizuku ©   (2005-01-17 13:48:00) 

Не удаётсявернуть результат (значение поля sum_result) в переменную DELPHI из следующего запроса:

SELECT
 sum(ANSWER.MARK) AS sum_result
FROM
 RESULT
 INNER JOIN ANSWER ON (RESULT.REPLY_ID = ANSWER.REPLY_ID)
WHERE
 (RESULT.USER_ID = :USER_ID) AND
 (RESULT.CREATED = 'NOW')


Запрос тестировалсяв EMS Interbase Manager - Query Builder, где прекрасно возращал требуемый результат.

Для возвратазначения используется код:

if (vartype(dm.IBQuery6.FieldValues['SUM_RESULT']) and
varTypeMask =varInteger) then
showmessage('Тест пройден. Сумма балов :'+string  <== Error %.%(dm.IBQuery6.FieldValues['sum_result']))
else
showmessage('Тест пройден. Сумма балов : 0');
end;

Если убрать условие- обработчик, то ошибка:

Project PRIPO.exe raised exception class EVariantTypeCastError
with message 'Could not convert variant of type (Null) into type (String)....'

В отладке:

(vartype(dm.IBQuery6.FieldValues['SUM_RESULT']) and
varTypeMask =varInteger) = inacessible value

dm.IBQuery6.FieldValues['SUM_RESULT']= null (врёт)

Испытывался итакой код:

showmessage('Тест пройден. Сумма балов :'+
dm.IBQuery6.FieldByName('sum_result').AsString)


Результат - пустая строка


Danilka   (2005-01-18 14:15:00) [1]

Врочем, ничего кроме лени не мешает там сделать свой аналог TRUNC.. :)


Danilka   (2005-01-18 14:14:00) [2]

[20] Johnmen ©   (17.01.05 22:02)
Угу, я про правую границу и не подумал.
Тяжело после ороклового TRUNC в других серверах с датами работать, прямо ломки.. :)


Johnmen   (2005-01-17 22:02:00) [3]

>Danilka ©  (17.01.05 15:49) [16]
>Johnmen ©  (17.01.05 16:30) [18]
>Да, всё верно :)

За исключением небольшого нюанса - правая граница не должна входить, т.е. надо

(CAST('TODAY' AS DATE) <= RESULT.CREATED )
AND
(RESULT.CREATED < CAST('TODAY' AS DATE)+1)


>msguns ©  (17.01.05 16:42) [19]

В принципе можно попытаться без "кусков"...:)


msguns   (2005-01-17 16:42:00) [4]

Джонмэн абсолютно прав в [15]. Я сам, пока не начал "кастать" дату по кускам не мог добиться правильно выборки документов за период. Фарьберд


Johnmen   (2005-01-17 16:30:00) [5]

>Danilka ©   (17.01.05 15:49) [16]

Да, всё верно :)


Shizuku   (2005-01-17 16:03:00) [6]

Польз. тестируется, потом надо подсчитать и выдать ему результат. Вы видели как мя решила эту проблему: выборка по user_id и created, где Created - дата занесения очередной результирующей записи в базу. Я боюсь, что при достаточно большом объеме теста, на операции сохранения и пр. уйдёт больше 1 секунды, и тогда последующая выборка со сравнением по NOW вернёт неполную сумму. Были испробованы различные варианты с like и betweeen, но стопроцентного решения как-то в голову не приходит.


Danilka   (2005-01-17 15:49:00) [7]

[15] Johnmen ©   (17.01.05 15:44)
TODAY - как я понимаю, это сегодня, с вырезаным временем?
тогда, может, проще что-то типа:
RESULT.CREATED BETWEEN CAST('TODAY' AS DATE) AND (CAST('TODAY' AS DATE)+1) ?

И индекс по полю CREATED будет участвовать.


Johnmen   (2005-01-17 15:44:00) [8]

Shizuku ©   (17.01.05 15:33) [14]

Тогда, если в поле типа DATE только дата без времени (время 00:00:00, то сравнивать надо
(RESULT.CREATED = CAST('TODAY' AS DATE))
А если есть и время, то (только для FB):
EXTRACT(YEAR FROM RESULT.CREATED)=EXTRACT(YEAR FROM CAST('TODAY' AS DATE)) AND
EXTRACT(MONTH FROM RESULT.CREATED)=EXTRACT(MONTH FROM CAST('TODAY' AS DATE)) AND
EXTRACT(DAY FROM RESULT.CREATED)=EXTRACT(DAY FROM CAST('TODAY' AS DATE))

Если же IB, то манипулировать операциями <,>,<=,>=


Shizuku   (2005-01-17 15:33:00) [9]

to Johnmen> у меня диалект 1
Где можно подробней про InterBase функции?
to Danilka> Спасибо огромное, работает. Облажалась мя позорно.


Johnmen   (2005-01-17 15:22:00) [10]

> (RESULT.CREATED = 'NOW')

Какого типа CREATED ?
(RESULT.CREATED = CAST('NOW' AS <тип CREATED>))
При этом
Если DATE в 1 диалекте, если TIMESTAMP в 3 диалекте, то такое сравнение всегда даст False.
И обрати внимание на 'TODAY'.


Shizuku   (2005-01-17 15:19:00) [11]

to Danilka> По форуму общение гораздо медленее - на то он и форум. У мя настолько узкий канал, что каждую страницу приходится ждать по пять минут, в лучшем случае.


Danilka   (2005-01-17 15:16:00) [12]

1. у тебя сначала:
dm.ibquery6.open;

а затем:
dm.IBQuery6.Params.ParamByName('user_id').AsString:= dm.ibquery4.FieldValues['user_id'];

а надо наоборот.
и на счет NOW, как справедливо заметил [9] Erik1, нет под рукой фиребирда чтобы проверит:
2. он нормально ее понимает, как дату или как строку?
3. эта ф-я возвращает дату и время с точностью до секунд? если да, то не подойдет она тебе, я так думаю..


Danilka   (2005-01-17 15:07:00) [13]

[7] Shizuku ©   (17.01.05 14:55)
Зачем аська, когда есть форум?


Erik1   (2005-01-17 15:07:00) [14]

А ты уверен, что это "(RESULT.CREATED = 'NOW')" то что тебе надо? Ведь 'NOW' это строка, да и USER_ID надо задавать.


Shizuku   (2005-01-17 15:07:00) [15]

Полный текст процедуры
===========================
procedure TFTest.Button1Click(Sender: TObject);
begin
if not addResult then
 Exit;
if dm.IBQuery2.active then
dm.ibquery2.close;
dm.ibquery2.open;
if dm.IBQuery2.FieldByName('QUESTION').AsString ='' then
begin
dm.ibquery6.open;

dm.IBScript1.ExecuteScript;
dm.IBScript1.Script.Clear;

dm.IBQuery6.Params.ParamByName('user_id').AsString:=
dm.ibquery4.FieldValues['user_id'];

//if (vartype(dm.IBQuery6.FieldValues['SUM_RESULT']) and
//varTypeMask =varInteger) then
//showmessage('Тест пройден. Сумма балов :'+string(dm.IBQuery6.FieldValues['sum_result']))
if dm.IBQuery6.FieldByName('SUM_RESULT').IsNull then
showmessage('Тест пройден. Сумма балов : NULL. Поля базы не заполнены.')
else
showmessage('Тест пройден. Сумма балов :'+
dm.IBQuery6.FieldByName('sum_result').AsString)
//else
//showmessage('Тест пройден. Сумма балов : 0');
end;
end;


Query4
=====================
select * from student

No comment ^_^


Shizuku   (2005-01-17 14:55:00) [16]

Плисс добавьте мя в Аську
ICQ: 229798623

Чё то тут не так...


Danilka   (2005-01-17 14:51:00) [17]

[5] Shizuku ©   (17.01.05 14:43)
Он тебе честно возвращаешь то, что ты просишь, ни больше не меньше. Если "на else не идёт", значит те условия, которые ты ему задал, всегдавозвращают NULL. Поэтому я и написал тебе: [2] Danilka ©   (17.01.05 14:06)


Shizuku   (2005-01-17 14:43:00) [18]

to Johnmen> на else не идёт. Но результат не может быть NULL, даже несмотря на то, что в запросе идёт сравнение с NOW. Записей мало, всё выполняется за время меньше секунды. Впрочем была попытка заменить NOW на обычную дату (прдварительно подсмотреную), результата тоже нет. А сам по себе запрос вернул всю сумму на дату.


Danilka   (2005-01-17 14:39:00) [19]

[3] Johnmen ©   (17.01.05 14:20)
Там нет нулла. Сказано-же - врет оно. :)


Johnmen   (2005-01-17 14:20:00) [20]

if dm.IBQuery6.FieldByName('SUM_RESULT').IsNull then
...
else
showmessage('Тест пройден. Сумма балов :'+
dm.IBQuery6.FieldByName('sum_result').AsString)


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо