У меня есть таблица с столбцом даты, который, как я знаю, хранится в GMT. У меня есть процедура, которая принимает ввод даты и идентификатор учетной записи. Процедура: 1) получает часовой пояс ID учетной записи (хранится в табличной учетной записи) 2) определяет начальный и конечный диапазон в GMT следующим образом: v_start_time: = cast (from_tz (cast (i_date as timestamp), v_tz) во времени zone c_gmt как дата); - где вводится i_date, v_tz - «US/Eastern» или любое другое имя tz из v $ timezone_names, а c_gmt - строка «GMT» v_end_time: = v_start_time + 1; - Добавить ровно один день, чтобы начать Дата 3) возвращение SYS_REFCURSOR абоненту как:Использование функции Oracle «в часовом поясе» в sql - проблема и решение
open o_cur for
select gmt_col, some_value
from my_table
where account_id = i_account_id
and gmt_col between v_start_time and v_end_time;
Однако разработчик хотел бы как gmt_date и местное время курсора. Во-первых, я пытался использовать один и тот же метод преобразования, как я должен был определить v_start_time, то есть:
open o_cur for
select gmt_col,
cast(from_tz(cast(gmt_col as timestamp), c_gmt) at time zone v_tz as date) as local_time, some_value
from my_table
where account_id = i_account_id
and gmt_col between v_start_time and v_end_time;
Однако, при компиляции, это приводит к ORA-00905: недостающее ключевое слово. Я попытался добавить одиночные кавычки вокруг «v_tz», например: chr (39) || v_tz || chr (39), но это не работает - proc компилируется, но когда я открываю курсор, я получаю ORA-01882: область часового пояса не найдена. После небольшого количества экспериментов, здесь есть два решения, которые позволяют "в часовом поясе" плавно работать в SQL:
РЕШЕНИЕ 1:
open o_cur for
select gmt_col,
cast(from_tz(cast(gmt_col as timestamp), c_gmt) at time zone (select v_tz from dual) as date) as local_time, some_value
from my_table
where account_id = i_account_id
and gmt_col between v_start_time and v_end_time;
РЕШЕНИЕ 2:
в спецификации пакета:
function echo(i_sound in varchar2) return varchar2;
pragma restrict_references(echo, wnps, rnps, wnds, rnds);
в теле пакета:
function echo(i_sound in varchar2) return varchar2 is begin return i_sound; end;
в процедуре:
open o_cur for
select gmt_col,
cast(from_tz(cast(gmt_col as timestamp), c_gmt) at time zone echo(v_tz) as date) as local_time, some_value
from my_table
where account_id = i_account_id
and gmt_col between v_start_time and v_end_time;
Производительность оказывается сравнимой для каждого. Второе решение намекает на то, что я недавно начал делать, а именно использовать функции для возврата «констант» с pragma restrict_references, поэтому я могу использовать постоянные значения гибко между pl / sql и sql. Например:
Функция c_gmt return varchar2; pragma restrict_references (c_gmt, wnds, rnds, wnps, rnps);
выберите * из v $ timezone_names где tzabbrev = c_gmt; выберите c_gmt из dual; v_start_time: = blah blah blah || c_gmt; и т. Д.
Прохладный, работает. Gracias. –