-
Есть таблица, в которой поля даты и времени - два разных поля. Нужно из таблицы выбрать записи в определенном временном интервале. Делал так:
S := '(SELECT Call,(DateQSO+TimeQSO) AS DateTimeQSO FROM RX4HX) AS L';
CommandText := 'SELECT Call, DateTimeQSO FROM ' + S + ' WHERE (L.DateTimeQSO >:DateTimeQSO)';
Не работает. Если поле DateTimeQSO (которое в исходной таблице не существует, а является суммой полей DateQSO+TimeQSO) заменить на поле, которое существует в исходной таблице - все работает. В чем моя ошибка?
-
ошибка в условии where
-
Почему не срабатывает составной запрос
потому что нет записей, удовлетворяющих условию where
-
Не работает, а что пишет?
-
> удовлетворяющих условию where
Почему нету? В параметр :DateTimeQSO я записываю заведомо существующий временной параметр. А записи НАОБОРОТ - все показываются, хотя должны только начиная во времени заданным параметром :DateTimtQSO.
-
Почему нету?
Потому что "не работает"
-
если б они были, сервер возвращал бы выборку.
-
> возвращал бы выборку.
Так он возвращает выборку. Только не поймешь какую.
Сейчас поэкспериментировал - вроде как получается ACCESS не умеет так делать?
Сейчас для пробы сделал так:
S := '(SELECT Call,(DateQSO+TimeQSO) AS DateTimeQSO FROM RX4HX) AS L';
with ADODataSet1 do
begin
Active := False;
CommandText := 'SELECT Call, DateTimeQSO FROM ' + S +
' WHERE (L.DateTimeQSO >:DateTimeQSO) ORDER BY L.DateTimeQSO';
ADODataSet1.Parameters.ParamByName('DateTimeQSO').Value := Now;
Active := True;
end;
Записей старше чем Now - нет. Однако возвращает записи и 2001-2011 годов. Причем не все- а часть. По какому принципу - не понятно :)
-
Alex_C (27.12.11 16:41) [4]
А какого типа поле TimeQSO ?
-
Все он умеет )
Напишите типы полей и что они содержат?
-
> А какого типа поле TimeQSO ?
В Accesse только одно поле есть DateTime - соответственно поля DateQSO и TimeQSO - поля типа DateTime.
Поле TimeQSO - содержит только время (значение меньше единицы.)
Пробовал так:
with ADODataSet1 do
begin
Active := False;
CommandText := 'SELECT Call,(DateQSO+TimeQSO) AS DateTimeQSO FROM RX4HX';
Active := True;
end;
Все отображается корректно.
-
with ADODataSet1 do
begin
Active := False;
CommandText := 'SELECT Call,(DateQSO+TimeQSO) AS DateTimeQSO FROM RX4HX WHERE (DateQSO+TimeQSO)> :(DateQSO+TimeQSO)';
Active := True;
end;
А Так?
-
т.е. так
'SELECT Call,(DateQSO+TimeQSO) AS DateTimeQSO FROM RX4HX WHERE (DateQSO+TimeQSO)> :DateTimeQSO';
-
что за идиотский стиль с "кусочничеством" в запросах... неужели нельзя нормально, цельно написать? тем более что этого куска не нужно вообще
+ второй параметр с тем же значением и проверяй за машиной... раз не веришь
with ADODataSet1 do begin
Close;
CommandText:=
'SELECT Call, DateQSO+TimeQSO AS DateTimeQSO,:DT FROM RX4HX '+
'WHERE (DateQSO+TimeQSO) > :DateTimeQSO '+
'ORDER BY 2';
Parameters.ParamByName('DT').Value:= Now;
Parameters.ParamByName('DateTimeQSO').Value:= Now;
Open;
end;
-
> А Так?
Так пробовал с самого начала - но, как я понял так точно не работает - после WHERE выражения не вычисляюся. Еще ранее в других местах пробовал - заставить вычисляться выражения не смог, вот способ с 2-я запросами и использовал.
Результат [12] аналогичен результату [7] - из 10 тыс записей, возвращается 1100, но логику возвращенных записей понять не смог - даты от 2001 до 2011 года.
-
И еще, не всегда корректно автоматически определяется тип параметров, лучше задавать явно.
-
> что за идиотский стиль
См. [14] - делал так с самого начала.
Результаты у [7],[12],[14] - один и тот же -
> из 10 тыс записей, возвращается 1100, но логику возвращенных
> записей понять не смог - даты от 2001 до 2011 года.
-
Alex_C (27.12.11 17:13) [14]
В самом акцессе пробовал? я даже сделал табличку наполнил и проверил :) все вычисляется и правильно работает.
-
> не всегда корректно автоматически определяется тип параметров
Да согласен - особенно это у DateTime чуствителен. Но тут все четко - все параметры заданы как DateTime.
-
> + второй параметр с тем же значением и проверяй за машиной.
> .. раз не веришь
На его месте пишется (VARBYTES) - по ходу все же это проблемы Access'а...
-
Еще раз хочу обратить внимание - если написать так
with ADODataSet1 do
begin
Close;
CommandText:=
'SELECT Call, DateQSO+TimeQSO AS DateTimeQSO FROM RX4HX '+
'WHERE Call = \"9E1S\" '+
'ORDER BY 2';
Open;
end;
Все правильно находится.
-
Так он возвращает выборку. Только не поймешь какую.
Он возвращает как раз поймешь какую выборку.
Ту, в которой записи, удовлетворяющие условию where
-
>На его месте пишется (VARBYTES) - по ходу все же это проблемы Access'а...
Значит тип параметра задан не верно.
-
Может я чего то не понимаю?
> Ту, в которой записи, удовлетворяющие условию where
Запрос был:
with ADODataSet1 do
begin
Active := False;
CommandText := 'SELECT Call,(DateQSO+TimeQSO) AS DateTimeQSO FROM RX4HX WHERE (DateQSO+TimeQSO)> :DateTimeQSO';
ADODataSet1.Parameters.ParamByName('DateTimeQSO').Value := Now;
Active := True;
end;
Вернулись записи:
OK1YDM 28.08.2001 8:06:00
ON4ADN 29.08.2001 8:33:00
...............
Каким образом эти записи соответствуют WHERE?
-
Каким образом эти записи соответствуют WHERE?
Прямым.
ps: а тебе зачем вообще sql сервер?
pps: если ты сам силой мысли можешь делать выборки, причем делаешь это правильнее чем сам сервер?
-
> Прямым.
Послушай, объясни толком - почему выборка этих значений является правильной?
Кстати если делать так
with ADODataSet1 do
begin
Active := False;
CommandText := 'SELECT Call,(DateQSO+TimeQSO) AS DateTimeQSO FROM RX4HX WHERE DateTimeQSO> :DateTimeQSO';
ADODataSet1.Parameters.ParamByName('DateTimeQSO').Value := Now;
Active := True;
end;
Пишет ошибку: Отсутствует значение для одного или нескольких требуемых параметров.
-
> Каким образом эти записи соответствуют WHERE?
> + второй параметр с тем же значением и проверяй за машиной... раз не веришь
-
> Пишет ошибку: Отсутствует значение для одного или нескольких требуемых параметров.
например ввел неправильное поле, которого нет, сам jet (не обертка/дельфи) в некоторых случаях считает неизвестное параметром.
-
Послушай, объясни толком - почему выборка этих значений является правильной?
Бессмысленный вопрос.
Выборку формирует сервер.
А сервер не виноват и всегда прав.
Кроме того, сервер писан не двоечниками и считать выражения умеет правильно в отличие от.
-
> неизвестное параметром.
понятно что
SELECT Call,(DateQSO+TimeQSO) AS DateTimeQSO FROM RX4HX WHERE DateTimeQSO> :DateTimeQSO
-
понятно что
хм скрипт кода переформатирует код... если стоит то
SELECT Call,(DateQSO+TimeQSO) AS DateTimeQSO FROM RX4HX WHERE DateTimeQSO> :DateTimeQSO
-
> А сервер не виноват и всегда прав.
Согласен. Я это и не оспариваю - я пытаюсь найти ошибку у себя - пока не получается.
[29] - Не понял ? Где проблема в этом выражении?
-
лет десять назад я бы взял и тупо бы добавил в список полей селекта сам параметр.
а потом посмотрел бы чему равно поле и чему равен параметр.
так я делал когда тоже считал, что иногда сервер вставляет в выборку не те записи что надо, и не вставляет те что надо.
-
> Не понял ? Где проблема в этом выражении?
у тебя есть в таблице поле DateTimeQSO? ну вот, получается jet-овский параметр сравниваешь с "дельфийским". причем jet-овский как пишет ошибка не инициализирован, без значения.
-
> лет десять назад я бы взял и тупо бы добавил в список полей селекта сам параметр.
> а потом посмотрел бы чему равно поле и чему равен параметр.
я ему предлагал... не проникся. ниче через 10 лет дойдет.
-
> у тебя есть в таблице поле DateTimeQSO?
Нет.
-
Для пробы попробовал так -
with ADODataSet1 do
begin
Active := False;
CommandText := 'SELECT Call,(DateQSO+TimeQSO) AS DateTimeQSO, :DT AS Hello FROM RX4HX WHERE (DateQSO+TimeQSO)>:DateTimeQSO';
ADODataSet1.Parameters.ParamByName('DateTimeQSO').Value := Now;
ADODataSet1.Parameters.ParamByName('DT').Value := 'Hello!';
Active := True;
end;
На месте :DT тоже пишется (VARBYTES) - параметр DT задак как стринг. Тоже не понятно почему...
-
CommandText := 'SELECT Call,(DateQSO+TimeQSO) AS DateTimeQSO FROM RX4HX WHERE DateTimeQSO> :DateTimeQSO';
Нельзя использовать алиас в выборке:
CommandText := 'SELECT Call,(DateQSO+TimeQSO) AS DateTimeQSO FROM RX4HX WHERE (DateQSO+TimeQSO)> :DateTimeQSO';
Сделай такой же запрос в акцессе и проверь выборку.
-
> параметр DT задак как стринг. Тоже не понятно почему...
??? задал и не понятно почему? само оно никак не задается (при "андефайне" дает по типу присваиваемого значения)
-
with ADODataSet1 do
begin
Active := False;
CommandText := 'SELECT Call,(DateQSO+TimeQSO) AS DateTimeQSO, :DT AS Hello FROM RX4HX WHERE (DateQSO+TimeQSO)>:DateTimeQSO';
ADODataSet1.Parameters.ParamByName('DateTimeQSO').DataType:=ftDateTime;
ADODataSet1.Parameters.ParamByName('DateTimeQSO').Value := Now;
ADODataSet1.Parameters.ParamByName('DT').DataType:=ftString;
ADODataSet1.Parameters.ParamByName('DT').Value := 'Hello!';
Active := True;
end;
-
> ADODataSet1.Parameters.ParamByName('DateTimeQSO').DataType:
> =ftDateTime;
Вот где собака порылась! Теперь все работает. Большое спасибо!
Остался только один для меня непонятный момент:
когда я создавал параметр DateTimeQSO в ObjectInspector'е - я там его тип как ftDateTime указывал. Получается нужно еще и руками прописывать?
Кстати если и так делать
ADODataSet1.Parameters.CreateParameter('DateTimeQSO', ftDateTime, pdInput, 0, NULL);
все равно нужно явно указывать тип параметра перед его использованием.
Странно, но нигде об этом не написано.
-
>когда я создавал параметр DateTimeQSO в ObjectInspector'е - я там его тип >как ftDateTime указывал.
Ты же Sql заменил потом.
-
> Ты же Sql заменил потом.
Имеется ввиду изменил из-за DateQSO+TimeQSO - тип результата не определен?
-
не из-за, а потому-что. заменил запрос, значит должен определить его переменные (или задать так чтобы самоопределилось), как локальные переменные в процедуре... то что относится к предыдущей для этой значения не имеет.
-
Alex_C (27.12.11 18:46) [42]
Ты SQL же меняешь в рантайм, у тебя уничтожаются все параметры и пересоздаются когда присваиваешь commandtext.
-
> пересоздаются когда присваиваешь commandtext.
Ну так они же должны пересоздаваться с изначальным типом? Причем это только для типа DateTime актуально - для остальных типов их снова указывать не надо.
> заменил запрос
Делал Prepared := True;
Все тоже самое.
Сейчас порылся в инете - по ходу это "фича" именно для Access+DateTime field type. В нескольких местах нашел, что для типа DateTime нужно делать как в [49].
Еще раз спасибо за подсказку!!!
-
> как в [49].
как в [39] :)
-
> Ну так они же должны пересоздаваться с изначальным типом?
кому должны? тебе? борланд перед тобой отчитыватся?
и не передергивай, было
> у тебя уничтожаются все параметры и пересоздаются когда присваиваешь commandtext.
какой там изначальный тип, у уничтоженного?
> что для типа DateTime нужно делать как в [49].
не выдумывай
сделай вот так, буквально
with ADODataSet1 do begin
CommandText := 'SELECT Call,(DateQSO+TimeQSO) AS DateTimeQSO, :DT AS Hello FROM RX4HX WHERE (DateQSO+TimeQSO)>:DateTimeQSO';
Parameters.ParamByName('DateTimeQSO').Value:= Now();
Parameters.ParamByName('DT').Value:= Now();
Open;
end;
в дизайне CommandText пустой.
-
> сделай вот так, буквально
Буквально вот так и сделано.
Сейчас уже поздно - завтра еще раз перепроверю - может где действительно CommandText переопределяю.
Кстати нашел очень хорошее объяснение этому всему:
http://drkb3.narod.ru/855.htmдумаю всем кто начинает работать с параметрами это прочитать обязательно!
-
> > Ну так они же должны пересоздаваться с изначальным типом?
>
> кому должны? тебе? борланд перед тобой отчитыватся?
Т.е. я правильно понимаю, если я создал в инспекторе объектов параметр с DataType = ftDateTime, я без боязни могу использовать только первый раз, и изменив CommandText , повторно параметр существовать будет, но его тип уже нужно повторно определить?
-
> повторно параметр существовать будет
совсем не обязательно, может и не существовать...
справку наконец то читать будем или нет?