将PIPELINED从Oracle迁移到Postgres

时间:2018-04-05 06:52:43

标签: sql postgresql

TYPE的创建如下:

create or replace  Type T_dates as OBJECT(
p_st_date VARCHAR2(32767),
p_en_date VARCHAR2(32767) 
);
create or replace  TYPE T_dates_tab AS table of T_dates;

需要转换的示例代码如下。 Oracle代码:

Function f_get_dates(p_st_date varchar2,
                     p_end_date varchar2,
                     p_st_time varchar2,
                     p_end_time varchar2) 
return  T_dates_tab PIPELINED 
IS 

V_DAY_COUNT NUMBER;
P_TEMP_ST_DATE VARCHAR2(100 ):=p_st_date;
BEGIN
    SELECT TO_DATE(p_end_date,'MM-DD-YYYY ') - TO_DATE(p_temp_st_date,'MM-DD-YYYY ') INTO V_DAY_COUNT FROM DUAL ;
    WHILE V_DAY_COUNT >= 0
    LOOP
      DBMS_OUTPUT.PUT_LINE(p_temp_st_date||' '||p_st_time||','||p_temp_st_date||' '||p_end_time);
      PIPE ROW (T_dates((p_temp_st_date||' '||p_st_time),(p_temp_st_date||' '||p_end_time)));
      SELECT TO_CHAR(TO_DATE(p_temp_st_date,'MM-DD-YYYY')+1,'MM/DD/YYYY') INTO p_temp_st_date FROM DUAL;
      SELECT TO_DATE(p_end_date,'MM-DD-YYYY ') - TO_DATE(p_temp_st_date,'MM-DD-YYYY ') INTO V_DAY_COUNT FROM DUAL ;

    END LOOP;

    DBMS_OUTPUT.PUT_LINE('f_get_dates');
    RETURN;

END f_get_dates;

需要Postgres输入以上的Oracle代码。

1 个答案:

答案 0 :(得分:1)

在Postgres中可以大大简化此功能。事实上,你并不真正需要自己的功能:

select p_st_date::date + time '00:00:00' as p_st_date, 
       p_st_date::date + time '18:00:00' as p_en_date
from generate_series(date '2018-01-01', date '2018-01-30', interval '1' day) as t(p_st_date);

与您的函数相比,它返回​​实时时间戳值而不是字符值。如果您确实要将时间戳值视为字符数据,请使用to_char()进行转换。

您可以将上述内容放入SQL函数中:

create function f_get_dates(p_st_date date, p_en_date date, p_st_time time, p_end_time time) 
  returns table (p_st_date timestamp, p_en_date timestamp)
as
$$
select p_st_date::date + p_st_time as p_st_date, 
       p_st_date::date + p_end_time as p_en_date
from generate_series(p_st_date, p_en_date, interval '1' day) as t(p_st_date);
$$
language sql;

如果您确实要将时间戳作为字符值返回,请使用to_char()格式化它们:

create function f_get_dates(p_st_date date, p_en_date date, p_st_time time, p_end_time time) 
  returns table (p_st_date varchar, p_en_date varchar)
as
$$
select to_char(p_st_date::date + p_st_time, 'mm-dd-yyyy hh24:mi:ss') as p_st_date, 
       to_char(p_st_date::date + p_end_time, 'mm-dd-yyyy hh24:mi:ss') as p_en_date
from generate_series(p_st_date, p_en_date, interval '1' day) as t(p_st_date);
$$
language sql;