Конференция "Базы" » Почему не срабатывает составной запрос [D7, Access]
 
  • Alex_C (27.12.11 16:18) [0]
    Есть таблица, в которой поля даты и времени - два разных поля. Нужно из таблицы выбрать записи в определенном временном интервале. Делал так:


     S := '(SELECT Call,(DateQSO+TimeQSO) AS DateTimeQSO FROM RX4HX) AS L';
     CommandText := 'SELECT Call, DateTimeQSO FROM ' + S + ' WHERE (L.DateTimeQSO >:DateTimeQSO)';



    Не работает. Если поле DateTimeQSO (которое в исходной таблице не существует, а является суммой полей DateQSO+TimeQSO) заменить на поле, которое существует в исходной таблице - все работает. В чем моя ошибка?
  • Медвежонок Пятачок © (27.12.11 16:26) [1]
    ошибка в условии where
  • Медвежонок Пятачок © (27.12.11 16:27) [2]
    Почему не срабатывает составной запрос

    потому что нет записей, удовлетворяющих условию where
  • stas © (27.12.11 16:27) [3]
    Не работает, а что пишет?
  • Alex_C (27.12.11 16:41) [4]

    > удовлетворяющих условию where


    Почему нету? В параметр :DateTimeQSO я записываю заведомо существующий временной параметр. А записи НАОБОРОТ - все показываются, хотя должны только начиная во времени заданным параметром :DateTimtQSO.
  • Медвежонок Пятачок © (27.12.11 16:47) [5]
    Почему нету?

    Потому что "не работает"
  • Медвежонок Пятачок © (27.12.11 16:48) [6]
    если б они были, сервер возвращал бы выборку.
  • Alex_C (27.12.11 16:57) [7]

    > возвращал бы выборку.


    Так он возвращает выборку. Только не поймешь какую.
    Сейчас поэкспериментировал - вроде как получается 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 годов. Причем не все- а часть. По какому принципу - не понятно :)
  • stas © (27.12.11 16:59) [8]
    Alex_C   (27.12.11 16:41) [4]
    А какого типа поле TimeQSO ?
  • stas © (27.12.11 17:00) [9]
    Все он умеет )
    Напишите типы полей и что они содержат?
  • Alex_C (27.12.11 17:04) [10]

    > А какого типа поле 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;



    Все отображается корректно.
  • stas © (27.12.11 17:08) [11]
    with ADODataSet1 do
    begin
     Active := False;
     CommandText := 'SELECT Call,(DateQSO+TimeQSO) AS DateTimeQSO FROM RX4HX WHERE (DateQSO+TimeQSO)> :(DateQSO+TimeQSO)';
     Active := True;
    end;

    А Так?
  • stas © (27.12.11 17:08) [12]
    т.е. так
    'SELECT Call,(DateQSO+TimeQSO) AS DateTimeQSO FROM RX4HX WHERE (DateQSO+TimeQSO)> :DateTimeQSO';
  • sniknik © (27.12.11 17:11) [13]
    что за идиотский стиль с "кусочничеством" в запросах... неужели нельзя нормально, цельно написать? тем более что этого куска не нужно вообще

    + второй параметр с тем же значением и проверяй за машиной... раз не веришь
     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;

  • Alex_C (27.12.11 17:13) [14]

    > А Так?


    Так пробовал с самого начала - но, как я понял так точно не работает - после WHERE выражения не вычисляюся. Еще ранее в других местах пробовал - заставить вычисляться выражения не смог, вот способ с 2-я запросами и использовал.

    Результат [12] аналогичен результату [7] - из 10 тыс записей, возвращается 1100, но логику возвращенных записей понять не смог - даты от 2001 до 2011 года.
  • stas © (27.12.11 17:16) [15]
    И еще, не всегда корректно автоматически определяется тип параметров, лучше задавать явно.
  • Alex_C (27.12.11 17:16) [16]

    > что за идиотский стиль


    См. [14] - делал так с самого начала.
    Результаты у [7],[12],[14] - один и тот же -
    > из 10 тыс записей, возвращается 1100, но логику возвращенных
    > записей понять не смог - даты от 2001 до 2011 года.
  • stas © (27.12.11 17:17) [17]
    Alex_C   (27.12.11 17:13) [14]
    В самом акцессе пробовал? я даже сделал табличку наполнил и проверил :) все вычисляется и правильно работает.
  • Alex_C (27.12.11 17:17) [18]

    > не всегда корректно автоматически определяется тип параметров


    Да согласен - особенно это у DateTime чуствителен. Но тут все четко - все параметры заданы как DateTime.
  • Alex_C (27.12.11 17:19) [19]

    > + второй параметр с тем же значением и проверяй за машиной.
    > .. раз не веришь


    На его месте пишется (VARBYTES) - по ходу все же это проблемы Access'а...
  • Alex_C (27.12.11 17:25) [20]
    Еще раз хочу обратить внимание - если написать так


     with ADODataSet1 do
     begin
      Close;
      CommandText:=
          'SELECT Call, DateQSO+TimeQSO AS DateTimeQSO FROM RX4HX '+
          'WHERE Call = \"9E1S\" '+
          'ORDER BY 2';
      Open;
    end;



    Все правильно находится.
  • Медвежонок Пятачок © (27.12.11 17:31) [21]
    Так он возвращает выборку. Только не поймешь какую.

    Он возвращает как раз поймешь какую выборку.
    Ту, в которой записи, удовлетворяющие условию where
  • stas © (27.12.11 17:35) [22]
    >На его месте пишется (VARBYTES) - по ходу все же это проблемы Access'а...
    Значит тип параметра задан не верно.
  • Alex_C (27.12.11 17:39) [23]
    Может я чего то не понимаю?

    > Ту, в которой записи, удовлетворяющие условию 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?
  • Медвежонок Пятачок © (27.12.11 17:44) [24]
    Каким образом эти записи соответствуют WHERE?

    Прямым.
    ps:  а тебе зачем вообще sql сервер?
    pps: если ты сам силой мысли можешь делать выборки, причем делаешь это правильнее чем сам сервер?
  • Alex_C (27.12.11 17:48) [25]

    > Прямым.


    Послушай, объясни толком - почему выборка этих значений является правильной?
    Кстати если делать так

     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;



    Пишет ошибку: Отсутствует значение для одного или нескольких требуемых параметров.
  • sniknik © (27.12.11 17:48) [26]
    > Каким образом эти записи соответствуют WHERE?
    > + второй параметр с тем же значением и проверяй за машиной... раз не веришь
  • sniknik © (27.12.11 17:50) [27]
    > Пишет ошибку: Отсутствует значение для одного или нескольких требуемых параметров.
    например ввел неправильное поле, которого нет, сам jet (не обертка/дельфи) в некоторых случаях считает неизвестное параметром.
  • Медвежонок Пятачок © (27.12.11 17:50) [28]
    Послушай, объясни толком - почему выборка этих значений является правильной?

    Бессмысленный вопрос.
    Выборку формирует сервер.
    А сервер не виноват и всегда прав.

    Кроме того, сервер писан не двоечниками и считать выражения умеет правильно в отличие от.
  • sniknik © (27.12.11 17:51) [29]
    > неизвестное параметром.
    понятно что
    SELECT Call,(DateQSO+TimeQSO) AS DateTimeQSO FROM RX4HX WHERE DateTimeQSO> :DateTimeQSO

  • sniknik © (27.12.11 17:53) [30]
    понятно что
    хм скрипт кода переформатирует код... если стоит то
    SELECT Call,(DateQSO+TimeQSO) AS DateTimeQSO FROM RX4HX WHERE DateTimeQSO> :DateTimeQSO
  • Alex_C (27.12.11 17:56) [31]

    > А сервер не виноват и всегда прав.

    Согласен. Я это и не оспариваю - я пытаюсь найти ошибку у себя - пока не получается.
    [29] - Не понял ? Где проблема в этом выражении?
  • Медвежонок Пятачок © (27.12.11 18:02) [32]
    лет десять назад я бы взял и тупо бы добавил в список полей селекта сам параметр.
    а потом посмотрел бы чему равно поле и чему равен параметр.

    так я делал когда тоже считал, что иногда сервер вставляет в выборку не те записи что надо, и не вставляет те что надо.
  • sniknik © (27.12.11 18:02) [33]
    > Не понял ? Где проблема в этом выражении?
    у тебя есть в таблице поле DateTimeQSO? ну вот, получается jet-овский параметр сравниваешь с "дельфийским". причем jet-овский как пишет ошибка не инициализирован, без значения.
  • sniknik © (27.12.11 18:04) [34]
    > лет десять назад я бы взял и тупо бы добавил в список полей селекта сам параметр.
    > а потом посмотрел бы чему равно поле и чему равен параметр.
    я ему предлагал... не проникся. ниче через 10 лет дойдет.
  • Alex_C (27.12.11 18:06) [35]

    > у тебя есть в таблице поле DateTimeQSO?


    Нет.
  • Alex_C (27.12.11 18:12) [36]
    Для пробы попробовал так -

     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 задак как стринг. Тоже не понятно почему...
  • stas © (27.12.11 18:13) [37]
     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';



    Сделай такой же запрос в акцессе и проверь выборку.
  • sniknik © (27.12.11 18:15) [38]
    > параметр DT задак как стринг. Тоже не понятно почему...
    ??? задал и не понятно почему? само оно никак не задается (при "андефайне" дает по типу присваиваемого значения)
  • stas © (27.12.11 18:15) [39]
    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;
  • Alex_C (27.12.11 18:34) [40]

    > ADODataSet1.Parameters.ParamByName('DateTimeQSO').DataType:
    > =ftDateTime;


    Вот где собака порылась! Теперь все работает. Большое спасибо!
    Остался только один для меня непонятный момент:
    когда я создавал параметр DateTimeQSO в ObjectInspector'е - я там его тип как ftDateTime указывал. Получается нужно еще и руками прописывать?
    Кстати если и так делать
    ADODataSet1.Parameters.CreateParameter('DateTimeQSO', ftDateTime, pdInput, 0, NULL);
    все равно нужно явно указывать тип параметра перед его использованием.
    Странно, но нигде об этом не написано.
  • stas © (27.12.11 18:40) [41]
    >когда я создавал параметр DateTimeQSO в ObjectInspector'е - я там его тип >как ftDateTime указывал.

    Ты же Sql заменил потом.
  • Alex_C (27.12.11 18:46) [42]

    > Ты же Sql заменил потом.


    Имеется ввиду изменил из-за DateQSO+TimeQSO - тип результата не определен?
  • sniknik © (27.12.11 19:43) [43]
    не из-за, а потому-что. заменил запрос, значит должен определить его переменные (или задать так чтобы самоопределилось), как локальные переменные в процедуре... то что относится к предыдущей для этой значения не имеет.
  • stas © (27.12.11 20:35) [44]
    Alex_C   (27.12.11 18:46) [42]
    Ты SQL же меняешь в рантайм, у тебя уничтожаются все параметры и пересоздаются когда присваиваешь commandtext.
  • Alex_C (27.12.11 22:50) [45]

    > пересоздаются когда присваиваешь commandtext.


    Ну так они же должны пересоздаваться с изначальным типом? Причем это только для типа DateTime актуально - для остальных типов их снова указывать не надо.


    > заменил запрос


    Делал Prepared := True;
    Все тоже самое.

    Сейчас порылся в инете - по ходу это "фича" именно для Access+DateTime field type. В нескольких местах нашел, что для типа DateTime нужно делать как в [49].
    Еще раз спасибо за подсказку!!!
  • Alex_C (27.12.11 22:51) [46]

    > как в [49].

    как в [39] :)
  • sniknik © (27.12.11 23:07) [47]
    > Ну так они же должны пересоздаваться с изначальным типом?
    кому должны? тебе? борланд перед тобой отчитыватся?
    и не передергивай, было
    > у тебя уничтожаются все параметры и пересоздаются когда присваиваешь 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 пустой.
  • Alex_C (27.12.11 23:17) [48]

    > сделай вот так, буквально

    Буквально вот так и сделано.
    Сейчас уже поздно - завтра еще раз перепроверю - может где действительно CommandText переопределяю.

    Кстати нашел очень хорошее объяснение этому всему:
    http://drkb3.narod.ru/855.htm
    думаю всем кто начинает работать с параметрами это прочитать обязательно!
  • Alex_C (27.12.11 23:21) [49]

    > > Ну так они же должны пересоздаваться с изначальным типом?
    >
    > кому должны? тебе? борланд перед тобой отчитыватся?


    Т.е. я правильно понимаю, если я создал в инспекторе объектов параметр с DataType = ftDateTime, я без боязни могу использовать только первый раз, и изменив CommandText , повторно параметр существовать будет, но его тип уже нужно повторно определить?
  • sniknik © (27.12.11 23:41) [50]
    > повторно параметр существовать будет
    совсем не обязательно, может и не существовать...

    справку наконец то читать будем или нет?
 
Конференция "Базы" » Почему не срабатывает составной запрос [D7, Access]
Есть новые Нет новых   [134431   +11][b:0][p:0.003]