我有一個表格,我知道存儲在格林尼治標準時間的日期列。我有一個接受日期輸入和帳戶ID的過程。程序: 1)獲取帳戶ID時區(存儲在表帳戶中) 2)確定GMT的開始和結束範圍,如下所示: v_start_time:= cast(from_tz(cast(i_date as timestamp),v_tz)at time區域c_gmt作爲日期); - 輸入i_date,v_tz是'US/Eastern'或來自v $ timezone_names的任何其他tzname,c_gmt是字符串'GMT' v_end_time:= v_start_time + 1; - 添加恰好一天開始日期 3)返回SYS_REFCURSOR給調用者:在SQL中使用Oracle「在時區」功能 - 問題和解決方案
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;
性能似乎是爲每個具有可比性。第二個解決方案暗示了我最近開始做的事情,即使用函數來返回帶有編譯指令restrict_references的「常量」,因此我可以在pl/sql和sql之間靈活地使用常量值。例如:
function c_gmt return varchar2; pragma restrict_references(c_gmt,wnds,rnds,wnps,rnps);
select * from v $ timezone_names where tzabbrev = c_gmt; 從雙重選擇c_gmt; v_start_time:= blah blah blah || c_gmt; 等...
很酷,有效。格拉西亞斯。 – 2010-11-11 20:11:22