尝试将TIMESTAMP
值转换为以参数(变量)形式给出的时区时,我收到了一个奇怪的错误。
以下代码抛出ORA-00907异常:
ORA-00907:缺少右括号
declare
tz timestamp := current_timestamp;
v_timezone varchar2(100) := '03:00';
tz2 timestamp;
begin
-- select (tz at time zone '03:00') into tz2 from dual;
select (tz at time zone v_timezone)
into tz2
from dual;
dbms_output.put_line(to_char(tz2,'hh24:mi:ss'));
-- dbms_output.put_line(to_char((tz at time zone v_timezone),'hh24:mi:ss'));
end;
同时,带字符串文字的SQL(第一个注释行)和带变量的PL / SQL(第二个注释行)都可以正常工作。
SQL中的变量有什么问题?为什么ORA-00907
?
答案 0 :(得分:4)
您需要将v_timezone变量括在braces()中,请参阅下面的代码
declare
tz timestamp := current_timestamp;
v_timezone varchar2(100) := '03:00';
tz2 timestamp;
begin
-- select (tz at time zone '03:00') into tz2 from dual;
-- either use it as
-- select tz at time zone (v_timezone)
-- or
-- select (tz at time zone (v_timezone) )
select (tz at time zone (v_timezone) )
into tz2
from dual;
dbms_output.put_line(to_char(tz2,'hh24:mi:ss'));
-- dbms_output.put_line(to_char((tz at time zone v_timezone),'hh24:mi:ss'));
end;
答案 1 :(得分:3)
AT TIME ZONE
需要文字或表达式:
expr AT { LOCAL | TIME ZONE { ' [ + | - ] hh:mi' | DBTIMEZONE | 'time_zone_name' | expr } }
它不喜欢变量。似乎变量被隐式地视为dbms_output
调用中的表达式,或任何PL / SQL上下文(正如Wernfried指出的那样,只有tz2 := tz at time zone v_timezone
也有效),这有点奇怪;但同样的事情并没有发生在SQL上下文中。
您可以通过将其包含在括号中或调用虚函数来强制将变量强制转换为表达式:
declare
tz timestamp := current_timestamp;
v_timezone varchar2(100) := '03:00';
tz2 timestamp;
begin
-- select (tz at time zone '03:00') into tz2 from dual;
select tz at time zone (v_timezone)
into tz2
from dual;
dbms_output.put_line(to_char(tz2,'hh24:mi:ss'));
-- dbms_output.put_line(to_char((tz at time zone v_timezone),'hh24:mi:ss'));
end;
PL/SQL procedure successfully completed.
17:45:41
基本上,删除你现在拥有的多余括号,并在变量周围使用虚拟括号。您可以使用函数,例如upper(v_timezone)
,但这不是必需的 - 只需要将它作为表达式进行求值的括号就足够了。奇怪但有效...它在bug 6113282中提到过,自9i以来似乎就像这样。