Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Миллисекунды в параметре запроса пропадают после второго вызова / 15 сообщений из 15, страница 1 из 1
13.05.2014, 13:00:57
    #38639685
sann-x
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Миллисекунды в параметре запроса пропадают после второго вызова
FB 2.5.2. Есть такой делфи-код:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
procedure TForm1.Button7Click(Sender: TObject);
const
  SQL_TEXT =
    'execute block (InParam timestamp = ?)'#13#10 +
      'returns (OutParam integer)'#13#10 +
    'as'#13#10 +
    'begin'#13#10 +
      'OutParam=extract(MILLISECOND from InParam);'#13#10 +
      'suspend;'#13#10 +
    'end'#13#10;

begin
  IBDatabase1.Open;
  try
    SQL_R.Close;
    SQL_R.SQL.Clear;
    SQL_R.SQL.Add(SQL_TEXT);
    SQL_R.Transaction.StartTransaction;
    try
      SQL_R.ParamCheck := False;
      SQL_R.Params.Count := 1;
      SQL_R.Params.AddName('prmDateTime', 0);
      SQL_R.ParamByName('prmDateTime').AsString := '29.11.1982 7:00:00.123';
      SQL_R.ExecQuery;
      ShowMessageFmt('%d', [SQL_R.FieldByName('OutParam').AsInteger]);
      SQL_R.Transaction.Commit;
    finally
      if SQL_R.Transaction.InTransaction then
        SQL_R.Transaction.Rollback;
      SQL_R.Close;
    end;
  finally
    IBDatabase1.Close;
  end;
end;


После запуска проги при первом нажатии на буттон7 ShowMessageFmt верно показывает 123 миллисекунды, однако при втором и далее нажатии на буттон7 показывается всегда 0. Это как так?
...
Рейтинг: 0 / 0
13.05.2014, 13:07:37
    #38639697
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Миллисекунды в параметре запроса пропадают после второго вызова
sann-xЭто как так?
Это так, что IBX вообще не умеет работать с долями секунды. Это у него врождённое.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
13.05.2014, 13:13:36
    #38639707
sann-x
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Миллисекунды в параметре запроса пропадают после второго вызова
Dimitry Sibiryakov,

Но в первый раз же IBSQL показал ведь миллисекунды, почему тогда после первого раза уже не показывает?
...
Рейтинг: 0 / 0
13.05.2014, 13:13:47
    #38639708
Мимопроходящий
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Миллисекунды в параметре запроса пропадают после второго вызова
Hello, Hvlad!
You wrote on 13 мая 2014 г. 13:11:28:

Hvlad> Это так, что IBX вообще не умеет работать с долями секунды.
> Это у него врождённое. занудства ради - IB API.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
13.05.2014, 13:16:20
    #38639715
Мимопроходящий
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Миллисекунды в параметре запроса пропадают после второго вызова
чо-то у меня квотер сломался.
пардону просим.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
13.05.2014, 13:38:16
    #38639746
sann-x
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Миллисекунды в параметре запроса пропадают после второго вызова
Посмотрел исходники "IBSQL.pas", метод "TIBXSQLVAR.SetAsString":
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
  if IsNullable then
    IsNull := False;
  stype := FXSQLVAR.SqlDef;
  if (stype = SQL_TEXT) or (stype = SQL_VARYING) then
    SetStringValue
  else
  begin
    if (stype = SQL_BLOB) then
    begin
      ss := TStringStream.Create(Value);
      try
        LoadFromStream(ss);
      finally
        ss.Free;
      end;
    end
    else
      if Value = '' then
        IsNull := True
      else
        // тута
        if (stype = SQL_TIMESTAMP) or (stype = SQL_TYPE_DATE) or
          (stype = SQL_TYPE_TIME) then
          SetAsDateTime(StrToDateTime(Value))
        else
        // и тута
          SetStringValue;
  end;



в первый раз stype = 0 и выполняется процедура SetStringValue, а после первого раза stype = 510 и выполняется метод SetAsDateTime, который, как известно, не передает миллисекунды в параметр. Вопрос: как "сбросить" stype, чтобы каждый раз выполнялась процедура SetStringValue?
...
Рейтинг: 0 / 0
13.05.2014, 13:50:57
    #38639761
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Миллисекунды в параметре запроса пропадают после второго вызова
sann-xВопрос: как "сбросить" stype, чтобы каждый раз выполнялась процедура
SetStringValue?
Вариант 1: не используй параметризованные запросы.
Вариант 2: присваивай значение сразу AsDateTime, а потом добавляй дробные доли секунды
непосредственно в формате TISC_TIMESTAMP через указатель Data.sqldata.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
13.05.2014, 13:55:01
    #38639767
sann-x
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Миллисекунды в параметре запроса пропадают после второго вызова
если сбрасывать вот так, то работает:
Код: pascal
1.
2.
3.
4.
  SQL_R.Params.Count := 1;
  SQL_R.Params.AddName('prmDateTime', 0);
  SQL_R.ParamByName('prmDateTime').Data.SqlType := 0;
  SQL_R.ParamByName('prmDateTime').AsString := '29.11.1982 7:00:00.123';


Можно ли считать такой способ валидным?
...
Рейтинг: 0 / 0
13.05.2014, 13:57:26
    #38639771
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Миллисекунды в параметре запроса пропадают после второго вызова
sann-xМожно ли считать такой способ валидным?
Это ещё худшее извращение, чем неиспользование параметров вообще.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
13.05.2014, 14:01:25
    #38639776
sann-x
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Миллисекунды в параметре запроса пропадают после второго вызова
Dimitry Sibiryakov,

Без параметров никак, ибо и меня "движок" выполнения запросов: указывается "номер" запроса из перечисления и параметры к нему. Запросов много, поэтому используется параметры. Чем этот код невалиден?
...
Рейтинг: 0 / 0
13.05.2014, 14:11:18
    #38639790
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Миллисекунды в параметре запроса пропадают после второго вызова
sann-xЧем этот код невалиден?
Он валиден, но крив. Имеет все недостатки неиспользования параметров, но гораздо длиннее.
Я бы рекомендовал повнимательнее рассмотреть вариант 2.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
13.05.2014, 14:58:01
    #38639856
sann-x
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Миллисекунды в параметре запроса пропадают после второго вызова
Dimitry Sibiryakov,

Сработал вариант 2. Получилось так:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
procedure TForm1.Button7Click(Sender: TObject);
const
  SQL_TEXT =
    'execute block (InParam timestamp = ?)'#13#10 +
      'returns (OutParam integer)'#13#10 +
    'as'#13#10 +
    'begin'#13#10 +
      'OutParam=extract(MILLISECOND from InParam);'#13#10 +
      'suspend;'#13#10 +
    'end'#13#10;

  IB_TIME_DIVIDER = 24 * 60 * 60 * 10000;

var
  ts: TISC_TIMESTAMP;
  dummy, ms: word;
  dt: TDateTime;
begin
  IBDatabase1.Open;
  try
    SQL_R.Close;
    SQL_R.SQL.Clear;
    SQL_R.SQL.Add(SQL_TEXT);
    SQL_R.Transaction.StartTransaction;
    try
      SQL_R.ParamCheck := False;
      SQL_R.Params.Count := 1;
      SQL_R.Params.AddName('prmDateTime', 0);
      dt := now;
      SQL_R.ParamByName('prmDateTime').AsDateTime := dt;

      // получить миллисекунды и прибавить их к Data.SqlData
      DecodeTime(dt, dummy, dummy, dummy, ms);
      ts := PISC_TIMESTAMP(SQL_R.ParamByName('prmDateTime').Data.SqlData)^;
      ts.timestamp_time := ts.timestamp_time + ms * 10;

      // учесть переполнение timestamp_time
      if ts.timestamp_time > IB_TIME_DIVIDER then
      begin
        ts.timestamp_date := ts.timestamp_date + 1;
        ts.timestamp_time := ts.timestamp_time - IB_TIME_DIVIDER;
      end;
      PISC_TIMESTAMP(SQL_R.ParamByName('prmDateTime').Data.SqlData)^ := ts;
      SQL_R.ExecQuery;
      ShowMessageFmt('%d', [SQL_R.FieldByName('OutParam').AsInteger]);
      SQL_R.Transaction.Commit;
    finally
      if SQL_R.Transaction.InTransaction then
        SQL_R.Transaction.Rollback;
      SQL_R.Close;
    end;
  finally
    IBDatabase1.Close;
  end;
end;


Спасибо!
...
Рейтинг: 0 / 0
13.05.2014, 15:56:35
    #38639942
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Миллисекунды в параметре запроса пропадают после второго вызова
sann-xПолучилось так:
Ужоснах.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
13.05.2014, 16:24:47
    #38639986
sann-x
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Миллисекунды в параметре запроса пропадают после второго вызова
Dimitry Sibiryakov,

А как надо, чтоб тип-топ?
...
Рейтинг: 0 / 0
13.05.2014, 18:16:34
    #38640154
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Миллисекунды в параметре запроса пропадают после второго вызова
sann-xА как надо, чтоб тип-топ?
А, извини, я совсем забыл, что IBX и EXECUTE BLOCK толком не поддерживает. Так что в коде
всё более-менее нормально, толко проверка на переполнение времени - лишняя. DecodeTime
хоть убейся не даст тебе больше 999 миллисекунд.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Миллисекунды в параметре запроса пропадают после второго вызова / 15 сообщений из 15, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]