2010-11-11 95 views
1

我有一個表格,我知道存儲在格林尼治標準時間的日期列。我有一個接受日期輸入和帳戶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; 等...

回答

4

你不應該需要從雙重額外的選擇。只要把變量放在括號裏就可以了(不要問我爲什麼):

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; 
+0

很酷,有效。格拉西亞斯。 – 2010-11-11 20:11:22