Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 timestamp with local time zone, dbms_scheduler  [new]
init.ora
Member

Откуда: гетто
Сообщений: 317
всем привет.

Дома воспроизвести не получается, но опишу суть ситуации, может кто знает в чем дело.

create table tst_tbl(d timestamp with local time zone);
---
insert into tst_tbl
select to_date('26.12.2013 00:00:00','dd.mm.yyyy hh24:mi:ss')+(level-1)/24
from dual
connect by level<=4;
---
create table tst_tbl2(a number);
---
create or replace procedure test_proc
as
begin
  execute immediate('truncate table tst_tbl2');
  ---
  insert into tst_tbl2
  select count(1)
  from tst_tbl where d between
  to_date('26.12.2013 00:00:00','dd.mm.yyyy hh24:mi:ss')
  and
  to_date('26.12.2013 03:00:00','dd.mm.yyyy hh24:mi:ss');
end;
---


Если выполнять процедуру из Pl\sql блока - все ожидаемо, в таблицу tst_tbl2 попадает 4 строки.
Но если ту же процедуру выполнить в джобе - не вставится ни одной строки..
Объясните, почему так.

при чем:
SQL> select sessiontimezone,dbtimezone
  2  from dual
  3  /

SESSIONTIMEZONE         DBTIMEZONE
----------------------- ----------
+04:00                  +00:00

SQL> select value
  2  from dba_scheduler_global_attribute
  3  where attribute_name = 'DEFAULT_TIMEZONE'
  4  /
 
VALUE
-----------------------------------
europe/moscow
26 дек 13, 22:12    [15352279]     Ответить | Цитировать Сообщить модератору
 Re: timestamp with local time zone, dbms_scheduler  [new]
eev
Member

Откуда: -
Сообщений: 1156
init.ora,

  insert into tst_tbl2....
commit;
end;
26 дек 13, 22:56    [15352416]     Ответить | Цитировать Сообщить модератору
 Re: timestamp with local time zone, dbms_scheduler  [new]
init.ora
Member

Откуда: гетто
Сообщений: 317
eev
init.ora,
  insert into tst_tbl2....
commit;
end;


нет, дело не в этом, а в каком-то непонятном для меня поведении timestamp with local time zone.

---
Например в таком случае в tst_tbl2 попадут не все 20 строк, а 16.


create table tst_tbl(d timestamp with local time zone);
---
insert into tst_tbl
select to_date('26.12.2013 00:00:00','dd.mm.yyyy hh24:mi:ss')+(level-1)/24
from dual
connect by level<=20;
---
create table tst_tbl2(a number);
---
create or replace procedure test_proc
as
begin
  execute immediate('truncate table tst_tbl2');
  ---
  insert into tst_tbl2
  select count(1)
  from tst_tbl where d between
  to_date('26.12.2013 00:00:00','dd.mm.yyyy hh24:mi:ss')
  and
  to_date('26.12.2013 10:00:00','dd.mm.yyyy hh24:mi:ss');
end;
26 дек 13, 23:09    [15352462]     Ответить | Цитировать Сообщить модератору
 Re: timestamp with local time zone, dbms_scheduler  [new]
SY
Member

Откуда: Middlebury, CT USA
Сообщений: 10051
init.ora
Если выполнять процедуру из Pl\sql блока - все ожидаемо, в таблицу tst_tbl2 попадает 4 строки.
Но если ту же процедуру выполнить в джобе - не вставится ни одной строки..
Объясните, почему так.


Как выполняется джоб? DBMS_SCHEDULER через AQ запускает процесс на сервере. DBTIMEZONE = 0.

SQL> select  d,
  2          d at time zone 'UTC'
  3    from  tst_tbl
  4  /

D                                                                           DATTIMEZONE'UTC'
--------------------------------------------------------------------------- ----------------------------------
26-DEC-13 12.00.00.000000 AM                                                25-DEC-13 09.00.00.000000 PM UTC
26-DEC-13 01.00.00.000000 AM                                                25-DEC-13 10.00.00.000000 PM UTC
26-DEC-13 02.00.00.000000 AM                                                25-DEC-13 11.00.00.000000 PM UTC
26-DEC-13 03.00.00.000000 AM                                                26-DEC-13 12.00.00.000000 AM UTC

SQL> 



SY.
26 дек 13, 23:47    [15352610]     Ответить | Цитировать Сообщить модератору
 Re: timestamp with local time zone, dbms_scheduler  [new]
init.ora
Member

Откуда: гетто
Сообщений: 317
SY
Как выполняется джоб? DBMS_SCHEDULER через AQ запускает процесс на сервере. DBTIMEZONE = 0.


 begin
  dbms_scheduler.create_job(
    job_name => 'testj',
    job_type => 'STORED_PROCEDURE',
    job_action => 'test_proc',
    enabled=>true
  );
end;


мне не понятно, почему при тех же значениях SESSIONTIMEZONE и DBTIMEZONE сейчас дома я не могу воспроизвести такое же поведение
=/
27 дек 13, 00:00    [15352676]     Ответить | Цитировать Сообщить модератору
 Re: timestamp with local time zone, dbms_scheduler  [new]
SY
Member

Откуда: Middlebury, CT USA
Сообщений: 10051
init.ora
мне не понятно, почему при тех же значениях SESSIONTIMEZONE и DBTIMEZONE сейчас дома я не могу воспроизвести такое же поведение


Ну сиди копайся, если некуда время девать. Проблема твоя в том что ты сравниваешь TS WITH LOCAL TZ c DATE. Это всегда приводит к плачевным результатам.

SY.
27 дек 13, 00:25    [15352761]     Ответить | Цитировать Сообщить модератору
 Re: timestamp with local time zone, dbms_scheduler  [new]
SY
Member

Откуда: Middlebury, CT USA
Сообщений: 10051
init.ora,

Даже без джоба понятно что твоя SP будет выдавать разные результаты клиентам в разных временных зонах:

SQL> select sessiontimezone,dbtimezone from dual;

SESSIONTIMEZONE                                                             DBTIME
--------------------------------------------------------------------------- ------
+04:00                                                                      +00:00

SQL> select * from tst_tbl;

D
---------------------------------------------------------------------------
26-DEC-13 12.00.00.000000 AM
26-DEC-13 01.00.00.000000 AM
26-DEC-13 02.00.00.000000 AM
26-DEC-13 03.00.00.000000 AM

SQL> create or replace procedure test_proc
  2  as
  3  begin
  4    execute immediate('truncate table tst_tbl2');
  5    ---
  6    insert into tst_tbl2
  7    select count(1)
  8    from tst_tbl where d between
  9    to_date('26.12.2013 00:00:00','dd.mm.yyyy hh24:mi:ss')
 10    and
 11    to_date('26.12.2013 03:00:00','dd.mm.yyyy hh24:mi:ss');
 12  end;
 13  /

Procedure created.

SQL> exec test_proc;

PL/SQL procedure successfully completed.

SQL> select * from tst_tbl2;

         A
----------
         4

SQL> alter session set time_zone='+05:00';

Session altered.

SQL> exec test_proc;

PL/SQL procedure successfully completed.

SQL> select * from tst_tbl2;

         A
----------
         3

SQL> alter session set time_zone='+06:00';

Session altered.

SQL> exec test_proc;

PL/SQL procedure successfully completed.

SQL> select * from tst_tbl2;

         A
----------
         2

SQL> alter session set time_zone='+07:00';

Session altered.

SQL> exec test_proc;

PL/SQL procedure successfully completed.

SQL> select * from tst_tbl2;

         A
----------
         1

SQL> alter session set time_zone='+08:00';

Session altered.

SQL> exec test_proc;

PL/SQL procedure successfully completed.

SQL> select * from tst_tbl2;

         A
----------
         0

SQL> 


SY.

Сообщение было отредактировано: 27 дек 13, 00:41
27 дек 13, 00:39    [15352784]     Ответить | Цитировать Сообщить модератору
 Re: timestamp with local time zone, dbms_scheduler  [new]
Вячеслав Любомудров
Member

Откуда: Владивосток
Сообщений: 18487
Посмотри, что кажет sessiontimezone внутри задания
27 дек 13, 01:48    [15352896]     Ответить | Цитировать Сообщить модератору
 Re: timestamp with local time zone, dbms_scheduler  [new]
SY
Member

Откуда: Middlebury, CT USA
Сообщений: 10051
Вячеслав Любомудров
Посмотри, что кажет sessiontimezone внутри задания


Вячеслав,

Так я же ему о том и твержу, да и не только в задании, а у любой сессии с другой временной зоной.

SY.
27 дек 13, 06:52    [15353073]     Ответить | Цитировать Сообщить модератору
 Re: timestamp with local time zone, dbms_scheduler  [new]
Вячеслав Любомудров
Member

Откуда: Владивосток
Сообщений: 18487
Будем считать, что я просто перевел твой тонкий намек немного толще
27 дек 13, 06:54    [15353077]     Ответить | Цитировать Сообщить модератору
 Re: timestamp with local time zone, dbms_scheduler  [new]
init.ora
Member

Откуда: гетто
Сообщений: 317
SY, Вячеслав Любомудров

Дык, это в первую очередь и сделал.

--таблица для записи dbtimezone, sessiontimezone в процедуре\джобе
create table t(dbtz varchar2(30), sesstz varchar2(30), dt date);

create or replace procedure test_proc
as
begin
  execute immediate('truncate table tst_tbl'); 
  ---
  insert into t values(dbtimezone, sessiontimezone, sysdate);
  ---
  insert /*+ append*/ into tst_tbl
  ---
  select <..запрос..>
  where 
  date_column between
  to_date('20.12.2013 14:34:00','dd.mm.yyyy hh24:mi:ss') 
  and 
  to_date('26.12.2013 12:34:00','dd.mm.yyyy hh24:mi:ss');
  commit;
end;


SQL> begin
  2    test_proc;
  3  end;
  4  /
 
PL/SQL procedure successfully completed
SQL> select count(1)
  2  from test_tbl
  3  /
 
  COUNT(1)
----------
     13565
SQL> begin
  2    dbms_scheduler.create_job(
  3      job_name => 'test_job',
  4      job_type => 'stored_procedure',
  5      job_action => 'test_proc',
  6      enabled=>true
  7    );
  8  end;
  9  /
 
PL/SQL procedure successfully completed
 
SQL> 
SQL> select count(1) /* выполняю через несколько секунд, после того, как джоб отработал */
  2  from test_tbl
  3  /
 
    COUNT(1)
-----------
      12134
	  
 SQL> select *
  2  from t
  3  /

DBTZ                           SESSTZ                         DT
------------------------------ ------------------------------ -------------------
+00:00                         +04:00                         27.12.2013 11:16:31 
+00:00                         +04:00                         27.12.2013 11:16:50 



Но если процедуру немного изменить:
create or replace procedure test_proc
as
begin
  execute immediate('alter session set time_zone = ''+04:00''');
  execute immediate('truncate table tst_tbl'); 
  ---
  insert into t values(dbtimezone, sessiontimezone, sysdate);
  ---
  insert /*+ append*/ into tst_tbl
  ---
  select <..запрос..>
  where 
  date_column between
  to_date('20.12.2013 14:34:00','dd.mm.yyyy hh24:mi:ss') 
  and 
  to_date('26.12.2013 12:34:00','dd.mm.yyyy hh24:mi:ss');
  commit;
end;




И затем выполнить те же действия, что и выше:

SQL> begin
  2    test_proc;
  3  end;
  4  /
 
PL/SQL procedure successfully completed
SQL> select count(1)
  2  from user_req_schema.WEB_REQ_415
  3  /
 
  COUNT(1)
----------
     13565
SQL> begin
  2    dbms_scheduler.create_job(
  3      job_name => 'test_job',
  4      job_type => 'stored_procedure',
  5      job_action => 'test_proc',
  6      enabled=>true
  7    );
  8  end;
 
  9  /
 
PL/SQL procedure successfully completed

 SQL> select count(1) /* выполняю через несколько секунд, после того, как джоб отработал */
  2  from test_tbl
  3  /
 
    COUNT(1)
-----------
      13565

--Результаты после выполнения джоба и процедуры в отдельном Pl\sql блоке получаются одинаковыми.
SQL> select *
  2  from t e order by dt
  3  /
 
DBTZ                           SESSTZ                         DT
------------------------------ ------------------------------ -------------------
+00:00                         +04:00                         27.12.2013 11:16:31
+00:00                         +04:00                         27.12.2013 11:16:50
+00:00                         +04:00                         27.12.2013 11:24:57
+00:00                         +04:00                         27.12.2013 11:25:29


dbtimezone, sessiontimezone во всех тестах одинаковые, но во втором примере "ALTER SESSION set time_zone" меняет результат для джоба.
28 дек 13, 18:57    [15359482]     Ответить | Цитировать Сообщить модератору
 Re: timestamp with local time zone, dbms_scheduler  [new]
SY
Member

Откуда: Middlebury, CT USA
Сообщений: 10051
init.ora
dbtimezone, sessiontimezone во всех тестах одинаковые, но во втором примере "ALTER SESSION set time_zone" меняет результат для джоба.


Ты вообще ответы внимательно читаешь: "Как выполняется джоб? DBMS_SCHEDULER через AQ запускает процесс на сервере. DBTIMEZONE = 0". T.e. session time zone сессии запущенной из background процессa (AQ в данном случае) естественно будет равна DBTIMEZONE, т.е. в данном случае 0. A dba_scheduler_global_attribute и/или start_date только влияют на временную зону даты запуска/перезапуска задания а не на временную зону сессии самого задания.

SY.
28 дек 13, 19:36    [15359610]     Ответить | Цитировать Сообщить модератору
 Re: timestamp with local time zone, dbms_scheduler  [new]
init.ora
Member

Откуда: гетто
Сообщений: 317
SY
T.e. session time zone сессии запущенной из background процессa (AQ в данном случае) естественно будет равна DBTIMEZONE, т.е. в данном случае 0
SY.


SY, спасибо за разъяснения, читаю внимательно, да.
Но я не понимаю, почему временная зона задания (выделено красным) одинаковая (почему в первом выделенном случае она не равна '+00:00'? Судя по тому что Вы написали, должно быть именно так, разве нет?), результаты - разные (в первом случае count(*) =12134, во втором count(*)=13565 ).

--Результаты после выполнения джоба и процедуры в отдельном Pl\sql блоке получаются одинаковыми.
SQL> select *
  2  from t e order by dt
  3  /
 
DBTZ                           SESSTZ                         DT
------------------------------ ------------------------------ -------------------
+00:00                         +04:00                         27.12.2013 11:16:31
+00:00                         +04:00                         27.12.2013 11:16:50
+00:00                         +04:00                         27.12.2013 11:24:57
+00:00                         +04:00                         27.12.2013 11:25:29


P.S. уяснил для себя одно-не надо сравнивать timestamp with local time zone с date
29 дек 13, 16:29    [15361509]     Ответить | Цитировать Сообщить модератору
 Re: timestamp with local time zone, dbms_scheduler  [new]
SY
Member

Откуда: Middlebury, CT USA
Сообщений: 10051
init.ora
Но я не понимаю, почему временная зона задания (выделено красным) одинаковая


А какая она должна быть если это TIMESTAMP WITH LOCAL TIME ZONE? Все что ты туда пихаешь переводится в UTC (т.е. к общему знаменателю) и так и хранится. А вот когда твоя сессия делает select, Oracle переводит это UTC значение в sessiontimezone, пoсему все значения и будут показывать временную зону твоей сессии. Измени её и получишь то же время в новой зоне:

SQL> select sessiontimezone from dual;

SESSIONTIMEZONE
---------------------------------------------
+01:00

SQL> select * from tst_tbl;

D
---------------------------------------------
25-DEC-13 09.00.00.000000 PM

SQL> alter session set time_zone= '-05:00';

Session altered.

SQL> select * from tst_tbl;

D
---------------------------------------------
25-DEC-13 03.00.00.000000 PM

SQL>


Т.е. когда в зоне +01:00 было 25-DEC-13 09.00.00.000000 PM, в зоне -05:00 было 25-DEC-13 03.00.00.000000 PM, что естественно, т.к. разница между зонами 6 часов.

SY.

Сообщение было отредактировано: 29 дек 13, 17:28
29 дек 13, 16:52    [15361565]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить