powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Многокр. вызов "timestamp 'now'" в ХП выдаёт одно и то же в отл. от cast(now as timestamp)
9 сообщений из 9, страница 1 из 1
Многокр. вызов "timestamp 'now'" в ХП выдаёт одно и то же в отл. от cast(now as timestamp)
    #38851334
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hi all

Дано: процедурка, извлекающая из текущего таймштампа миллисекунды по отн. к фиксированной дате 01-янв-2010, и сохраняющая эти миллисеки в контекстной переменной:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
create or alter procedure sp_ctx_test returns( ms bigint, ms_ctx bigint )
as
begin
    --ms = datediff(millisecond from timestamp '01.01.2010 00:00:00' to timestamp 'now');
    ms = datediff(millisecond from timestamp '01.01.2010 00:00:00' to cast( 'now' as timestamp) );
    rdb$set_context('USER_TRANSACTION','DBG_DTS', ms );
    ms_ctx = cast(rdb$get_context('USER_TRANSACTION','DBG_DTS') as bigint);
end

Замена строки:
Код: plaintext
    ms = datediff(millisecond from timestamp '01.01.2010 00:00:00' to cast( 'now' as timestamp) );
на ту, что сейчас закомментарена:
Код: plaintext
    ms = datediff(millisecond from timestamp '01.01.2010 00:00:00' to  timestamp 'now' );
- приводит к возврату из этой ХП всегда одного и того же значения таймштампа (того, что будет при первом вызове).

Но паазвольте-с! Я ведь не обращаюсь к current_timestamp 'у, а вызываю именно 'now' . Что не так ?
...
Рейтинг: 0 / 0
Многокр. вызов "timestamp 'now'" в ХП выдаёт одно и то же в отл. от cast(now as timestamp)
    #38851340
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ТаблоидЯ ведь не обращаюсь к current_timestamp'у, а вызываю именно'now'. Что не так
?
Ты не отличаешь литерала от вызова функции. timestamp 'что угодно' - это литерал, он
вычисляется при компиляции.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Многокр. вызов "timestamp 'now'" в ХП выдаёт одно и то же в отл. от cast(now as timestamp)
    #38851355
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
да, что-то тупанул я к вечеру ближе....
спс.
...
Рейтинг: 0 / 0
Многокр. вызов "timestamp 'now'" в ХП выдаёт одно и то же в отл. от cast(now as timestamp)
    #39141541
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovТаблоидЯ ведь не обращаюсь к current_timestamp'у, а вызываю именно'now'. Что не так
?Ты не отличаешь литерала от вызова функции. timestamp 'что угодно' - это литерал, он вычисляется при компиляции.Извиняйте, что поднимаю тему, но по-прежнему "беспокоит меня девятый стул" (С).
Вот скрипт, с двумя execute block'ами. Он выдаст при каждом своём вызове две строки: одну с datediff'ами, вычисленными по внутренним переменным execute block'a (они названы t0a, t0b & t1), а вторую - с datediff'ами, вычисленным по out-параметрам execute block'a (у них те же имена):
Код: plaintext
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.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
set bail on;
set heading off;
set term ^;
execute block returns(elapsed_1 int, elapsed_2 int) as
  declare t0a timestamp;
  declare t0b timestamp;
  declare t1 timestamp;
  declare c1 int;
  declare c2 int;
  declare c3 int;
  declare c4 int;
begin
  t0a = timestamp 'now';
  t0b = 'now';

    with recursive
    r1 as (
      select 1 as i from rdb$database
      union all
      select r.i+1 from r1 r where r.i < 2
    )
    --select count(*) from r1;

    ,r2 as (
      select first 1 row_number() over() i 
      from r1 ra
      full join r1 rb on rb.i=ra.i 
      group by ra.i 
      having count(*)>0 

      union all

      select rx.i+1 from r2 rx
      where rx.i+1 <= 2
    )
    --select count(*) from r2
    ,r3 as (
      select first 1 row_number() over() i 
      from r2 ra
      full join r2 rb on rb.i=ra.i 
      group by ra.i 
      having count(*)>0 

      union all

      select rx.i+1 from r3 rx
      where rx.i+1 <= 2
    )
    --select count(*) from r3
    ,r4 as (
      select first 1 row_number() over() i 
      from r3 ra
      full join r3 rb on rb.i=ra.i 
      group by ra.i 
      having count(*)>0 

      union all

      select rx.i+1 from r4 rx
      where rx.i+1 <= 2
    )
    ,rn as (
      select row_number() over() i 
      from rdb$database r full join rdb$database r2 on r2.rdb$relation_id=r.rdb$relation_id 
      group by r.rdb$relation_id 
      having count(*)>0 
      order by r.rdb$relation_id 
      rows 1 to 1
    )
    select 
        char_length(mon$explained_plan)
       ,(select count(*) from r4)
       ,(select count(*) from rn)
       ,(select count(*) from rn)
    from mon$statements
    into c1,c2,c3,c4
    ;

  --select count(*) from rdb$types, rdb$types, (select 1 i from rdb$types rows 10) into c;
  t1 = timestamp 'now';

  elapsed_1 = datediff(millisecond from t0a to t1);
  elapsed_2 = datediff(millisecond from t0b to t1);
  suspend;
end
^

execute block returns(
  t0a timestamp
  ,t0b timestamp
  ,t1 timestamp
  ,elapsed_1 int
  ,elapsed_2 int
) as
  declare c1 int;
  declare c2 int;
  declare c3 int;
  declare c4 int;
begin
  t0a = timestamp 'now';
  t0b = 'now';


    with recursive
    r1 as (
      select 1 as i from rdb$database
      union all
      select r.i+1 from r1 r where r.i < 2
    )
    --select count(*) from r1;

    ,r2 as (
      select first 1 row_number() over() i 
      from r1 ra
      full join r1 rb on rb.i=ra.i 
      group by ra.i 
      having count(*)>0 

      union all

      select rx.i+1 from r2 rx
      where rx.i+1 <= 2
    )
    --select count(*) from r2
    ,r3 as (
      select first 1 row_number() over() i 
      from r2 ra
      full join r2 rb on rb.i=ra.i 
      group by ra.i 
      having count(*)>0 

      union all

      select rx.i+1 from r3 rx
      where rx.i+1 <= 2
    )
    --select count(*) from r3
    ,r4 as (
      select first 1 row_number() over() i 
      from r3 ra
      full join r3 rb on rb.i=ra.i 
      group by ra.i 
      having count(*)>0 

      union all

      select rx.i+1 from r4 rx
      where rx.i+1 <= 2
    )
    ,rn as (
      select row_number() over() i 
      from rdb$database r full join rdb$database r2 on r2.rdb$relation_id=r.rdb$relation_id 
      group by r.rdb$relation_id 
      having count(*)>0 
      order by r.rdb$relation_id 
      rows 1 to 1
    )
    select 
        char_length(mon$explained_plan)
       ,(select count(*) from r4)
       ,(select count(*) from rn)
       ,(select count(*) from rn)
    from mon$statements
    into c1,c2,c3,c4
    ;

  --select count(*) from rdb$types, rdb$types, (select 1 i from rdb$types rows 0) into c;
  t1 = timestamp 'now';

  elapsed_1 = datediff(millisecond from t0a to t1);
  elapsed_2 = datediff(millisecond from t0b to t1);
  suspend;
end
^
set term ;^

А вот батник для работы с вышепоказанным скриптом (они должны иметь одинаковое имя):
Код: plaintext
1.
2.
3.
4.
5.
@echo off
del %~n0.log 2>nul
for /l %%i in (1,1,10) do (
  isql /3333:e30 -i %~n0.sql 1>>%~n0.log 2>&1
)
findstr /r /v /c:"^$" %~n0.log

А вот результат работы батника (нечётные строки - когда таймштампы задавались во внутренних переменных, чётные - когда в out-параметрах):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
          46          -16
2016-01-03 12:46:10.4530  2016-01-03 12:46:10.4680  2016-01-03 12:46:10.4530             0          -15
          15            0
2016-01-03 12:46:10.8590  2016-01-03 12:46:10.8750  2016-01-03 12:46:10.8590             0          -16
           0          -16
2016-01-03 12:46:11.1870  2016-01-03 12:46:11.2030  2016-01-03 12:46:11.2030            16            0
           0          -16
2016-01-03 12:46:11.5150  2016-01-03 12:46:11.5310  2016-01-03 12:46:11.5150             0          -16
           0          -16
2016-01-03 12:46:11.8280  2016-01-03 12:46:11.8430  2016-01-03 12:46:11.8280             0          -15
           0          -15
2016-01-03 12:46:12.1400  2016-01-03 12:46:12.1560  2016-01-03 12:46:12.1400             0          -16
           0          -16
2016-01-03 12:46:12.4680  2016-01-03 12:46:12.4840  2016-01-03 12:46:12.4680             0          -16
           0          -16
2016-01-03 12:46:12.9060  2016-01-03 12:46:12.9210  2016-01-03 12:46:12.9060             0          -15
           0          -15
2016-01-03 12:46:13.2340  2016-01-03 12:46:13.2500  2016-01-03 12:46:13.2340             0          -16
           0          -16
2016-01-03 12:46:13.5460  2016-01-03 12:46:13.5620  2016-01-03 12:46:13.5460             0          -16
А теперь - имею что спросить.
1) первое из чисел в каждом кортеже (незав. от EB) - это дифферент между
Код: plaintext
t0a = timestamp 'now';
и
Код: plaintext
t1 = timestamp 'now';
Но если оба они есть литералы, вычисляемые на фазе компиляции, то откуда там 46 мс и 15 мс в кортежах 1 и 3, а также 16 мс в кортеже 6 ?
2) второе из чисел - это дифферент между
Код: plaintext
t0b = 'now';
и
Код: plaintext
t1 = timestamp 'now';
С какого перепугу первый из этих моментов почти каждый раз "уходит вперёд" второго ?!
...
Рейтинг: 0 / 0
Многокр. вызов "timestamp 'now'" в ХП выдаёт одно и то же в отл. от cast(now as timestamp)
    #39141551
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
t0a - время, когда парсер добрался до строки
Код: plaintext
t0a = timestamp 'now';

t1 - время, когда парсер добрался до строки
Код: plaintext
t1 = timestamp 'now';

t0b - время, когда выполнялась строка
Код: plaintext
t0b = 'now';

Дальше надо объяснять ?
...
Рейтинг: 0 / 0
Многокр. вызов "timestamp 'now'" в ХП выдаёт одно и то же в отл. от cast(now as timestamp)
    #39141623
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvladt0a - время, когда парсер добрался до строки
Код: plaintext
t0a = timestamp 'now';

t1 - время, когда парсер добрался до строки
Код: plaintext
t1 = timestamp 'now';

t0b - время, когда выполнялась строка
Код: plaintext
t0b = 'now';

Дальше надо объяснять ?да, хотелось бы тут подробнее.
Вот есть "поток входных байтов":
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
execute block returns(elapsed_1 int, elapsed_2 int) as
  declare t0a timestamp;
  declare t0b timestamp;
  declare t1 timestamp;
  declare c1 int;
  declare c2 int;
  declare c3 int;
  declare c4 int;
begin
  t0a = timestamp 'now'; -- это отобразится в виде " восстановленного " момента_А, когда  ранее  на этой строке был парсер
   t0b  = 'now'; -- это отобразится в виде " текущего " момента_Б, когда эта строка выполнится  в рантайме 
  . . . дальше чудо-юдо в виде with-select'a . . .
   t1  = timestamp 'now'; -- это отобразится в виде " восстановленного " момента_1, когда  ранее  на этой строке был парсер

  elapsed_1 = datediff(millisecond from t0a to t1);
  elapsed_2 = datediff(millisecond from t0b to t1);
  suspend;
end

Результат для 10 запусков:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
 46          -16
 15            0
  0          -16
  0          -16
  0          -16
  0          -15
  0          -16
  0          -16
  0          -15
  0          -16
- мне не понятен, от слова "вообще" (за исключением левого столбца, где все числа >=0).
Каким способом значение в переменную t0b заехало (в рантайме !) раньше на 16 мс, чем компилятор этого EB глядел на строку, в которой идёт присваивание ' t1 ' ?
И есл так и должно было быть, то почему во второй строке записано ноль вместо минусового числа ?
...
Рейтинг: 0 / 0
Многокр. вызов "timestamp 'now'" в ХП выдаёт одно и то же в отл. от cast(now as timestamp)
    #39141624
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Таблоидзначение в переменную t0b заехало раньше на 16 мс
Позже
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Многокр. вызов "timestamp 'now'" в ХП выдаёт одно и то же в отл. от cast(now as timestamp)
    #39141627
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov,

да, согласен; всё-таки тупняк мой не лечится почему-то :-/
Но и засада с этими var1 = timestamp 'now' vs var2 = 'now' - тоже есть.
...
Рейтинг: 0 / 0
Многокр. вызов "timestamp 'now'" в ХП выдаёт одно и то же в отл. от cast(now as timestamp)
    #39141634
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Таблоидтоже есть.
Нету. Просто надо помнить,что 16 мс это квант времени в Windows.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Многокр. вызов "timestamp 'now'" в ХП выдаёт одно и то же в отл. от cast(now as timestamp)
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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