![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Вернуть результат из вычисляемого поля запроса [D7, IB6.x, FireBird]
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)