PL/SQL 函数值的间隔精度

发布于 2024-09-03 20:19:42 字数 1748 浏览 3 评论 0原文

通常,当您指定函数时,返回数据类型的小数位数/精度/大小是未定义的。

例如,您输入 FUNCTION show_price RETURN NUMBERFUNCTION show_name RETURN VARCHAR2

不允许使用 FUNCTION show_price RETURN NUMBER(10,2)FUNCTION show_name RETURN VARCHAR2(20),并且函数返回值不受限制。 这是已记录的功能。

现在,如果我将 9999 小时(大约 400 天)推入以下内容,则会出现精度错误 (ORA-01873)。该限制是因为 默认天数精度为 2< /a>

DECLARE
  v_int INTERVAL DAY (4) TO SECOND(0);
  FUNCTION hhmm_to_interval return INTERVAL DAY TO SECOND IS
    v_hhmm INTERVAL DAY (4) TO SECOND(0);
  BEGIN
    v_hhmm := to_dsinterval('PT9999H');
    RETURN v_hhmm;
    --
  END hhmm_to_interval;
BEGIN
  v_int := hhmm_to_interval;
end;
/

并且它不允许将精度直接指定为函数返回的数据类型的一部分。

DECLARE
  v_int INTERVAL DAY (4) TO SECOND(0);
  FUNCTION hhmm_to_interval return INTERVAL DAY (4) TO SECOND IS
    v_hhmm INTERVAL DAY (4) TO SECOND(0);
  BEGIN
    v_hhmm := to_dsinterval('PT9999H');
    RETURN v_hhmm;
    --
  END hhmm_to_interval;
BEGIN
  v_int := hhmm_to_interval;
end;
/

我可以使用 SUBTYPE 子

DECLARE
  subtype t_int is INTERVAL DAY (4) TO SECOND(0);
  v_int INTERVAL DAY (4) TO SECOND(0);
  FUNCTION hhmm_to_interval return t_int IS
    v_hhmm INTERVAL DAY (4) TO SECOND(0);
  BEGIN
    v_hhmm := to_dsinterval('PT9999H');
    RETURN v_hhmm;
    --
  END hhmm_to_interval;
BEGIN
  v_int := hhmm_to_interval;
end;
/

类型方法有什么缺点吗?

任何替代方案(例如更改默认精度的某个地方)?

使用 10gR2。

Generally, when you specify a function the scale/precision/size of the return datatype is undefined.

For example, you say FUNCTION show_price RETURN NUMBER or FUNCTION show_name RETURN VARCHAR2.

You are not allowed to have FUNCTION show_price RETURN NUMBER(10,2) or FUNCTION show_name RETURN VARCHAR2(20), and the function return value is unrestricted. This is documented functionality.

Now, I get an precision error (ORA-01873) if I push 9999 hours (about 400 days) into the following. The limit is because the default days precision is 2

DECLARE
  v_int INTERVAL DAY (4) TO SECOND(0);
  FUNCTION hhmm_to_interval return INTERVAL DAY TO SECOND IS
    v_hhmm INTERVAL DAY (4) TO SECOND(0);
  BEGIN
    v_hhmm := to_dsinterval('PT9999H');
    RETURN v_hhmm;
    --
  END hhmm_to_interval;
BEGIN
  v_int := hhmm_to_interval;
end;
/

and it won't allow the precision to be specified directly as part of the datatype returned by the function.

DECLARE
  v_int INTERVAL DAY (4) TO SECOND(0);
  FUNCTION hhmm_to_interval return INTERVAL DAY (4) TO SECOND IS
    v_hhmm INTERVAL DAY (4) TO SECOND(0);
  BEGIN
    v_hhmm := to_dsinterval('PT9999H');
    RETURN v_hhmm;
    --
  END hhmm_to_interval;
BEGIN
  v_int := hhmm_to_interval;
end;
/

I can use a SUBTYPE

DECLARE
  subtype t_int is INTERVAL DAY (4) TO SECOND(0);
  v_int INTERVAL DAY (4) TO SECOND(0);
  FUNCTION hhmm_to_interval return t_int IS
    v_hhmm INTERVAL DAY (4) TO SECOND(0);
  BEGIN
    v_hhmm := to_dsinterval('PT9999H');
    RETURN v_hhmm;
    --
  END hhmm_to_interval;
BEGIN
  v_int := hhmm_to_interval;
end;
/

Any drawbacks to the subtype approach ?

Any alternatives (eg some place to change a default precision) ?

Working with 10gR2.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

亚希 2024-09-10 20:19:42

我能想到的没有真正的缺点。 会更清楚一些。

DECLARE 
  subtype t_int is INTERVAL DAY (4) TO SECOND(0);

  v_int t_int;

  FUNCTION hhmm_to_interval return t_int IS 
    v_hhmm t_int; 
  BEGIN 
    v_hhmm := to_dsinterval('PT9999H'); 
    RETURN v_hhmm; 
  END hhmm_to_interval; 

BEGIN 
  v_int := hhmm_to_interval;
  DBMS_OUTPUT.PUT_LINE('v_int=' || v_int);
end; 

我认为如果将工作变量声明为子类型的实例,例如:共享和享受,

No real drawbacks that I can think of. I think it would be a bit more clear if the working variables were declarred as instances of the subtype, e.g.:

DECLARE 
  subtype t_int is INTERVAL DAY (4) TO SECOND(0);

  v_int t_int;

  FUNCTION hhmm_to_interval return t_int IS 
    v_hhmm t_int; 
  BEGIN 
    v_hhmm := to_dsinterval('PT9999H'); 
    RETURN v_hhmm; 
  END hhmm_to_interval; 

BEGIN 
  v_int := hhmm_to_interval;
  DBMS_OUTPUT.PUT_LINE('v_int=' || v_int);
end; 

Share and enjoy.

云朵有点甜 2024-09-10 20:19:42

Oracle 为此目的提供了一些内置子类型,请参阅避免使用日期和时间子类型的截断问题

它们是:

TIMESTAMP_UNCONSTRAINED
TIMESTAMP_TZ_UNCONSTRAINED
TIMESTAMP_LTZ_UNCONSTRAINED
YMINTERVAL_UNCONSTRAINED
DSINTERVAL_UNCONSTRAINED

Oracle provides some build-in subtypes for that purpose, see Avoiding Truncation Problems Using Date and Time Subtypes

They are:

TIMESTAMP_UNCONSTRAINED
TIMESTAMP_TZ_UNCONSTRAINED
TIMESTAMP_LTZ_UNCONSTRAINED
YMINTERVAL_UNCONSTRAINED
DSINTERVAL_UNCONSTRAINED
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文