Can you please help to convert below Oracle function to PostgreSQL function?
CREATE OR REPLACE FUNCTION CONVERT_TIME (DATETIME IN TIMESTAMP, TZ1 IN VARCHAR2, TZ2 IN VARCHAR2)
RETURN DATE
AS
RETVAL DATE;
BEGIN
RETVAL := FROM_TZ(TO_TIMESTAMP(TO_CHAR(DATETIME,'YYYY-MM-DD HH:MI:SS AM'),'YYYY-MM-DD HH:MI:SS AM'), TZ_OFFSET (TZ1)) AT TIME ZONE TZ_OFFSET (TZ2);
RETURN RETVAL;
END;
/
Related
I'm trying to create user-defined function which will return SUM from expenses view based on given dates.
CREATE FUNCTION budget.getTotalAmountFromView (startDate DATE, endDate DATE)
RETURNS DECIMAL AS $$
DECLARE
totalValue DECIMAL := 0;
BEGIN
SELECT INTO totalValue sum(amount) from budget.epenses_overview where transaction_date >= startDate AND transaction_date <= endDate;
RETURN totalValue;
END;
$$ LANGUAGE plpgsql;
I am trying to invoke it using:
SELECT * FROM budget.getTotalAmountFromView(TO_DATE(20190201, YYYYMMDD), TO_DATE(20190225, YYYYMMDD));
But it returns error
AFTER CHANGES:
Function shall be assigned to the right schema -> budget;
and invoke:
SELECT budget.getTotalAmountFromView('20190201'::DATE, '20190225'::DATE);
You don't need FROM for scalar function:
SELECT budget.getTotalAmountFromView22('20190201'::DATE, '20190225'::DATE);
You are lacking single quotes around the date and format strings.
TO_DATE(20190201, YYYYMMDD) should be TO_DATE('20190201', 'YYYYMMDD')
I want to get milliseconds from a 'Timestamp with timezone' using a plsql function.
I am able to generate the following function, but it is leading to truncation of miliseconds.
CREATE or REPLACE FUNCTION getMSFromTime(t1 timestamp with time zone)
RETURNS bigint AS $$
declare time1 double precision ;
BEGIN
SELECT EXTRACT(EPOCH FROM t1) into time1;
return time1;
END;
$$ LANGUAGE plpgsql;
but it ignores miliseconds
SELECT getMSFromTime('2019-02-11 08:01:33.423+00') //1549872093
SELECT getMSFromTime('2019-02-11 08:01:33.000+00') //1549872093
I am able to get a PostgreSQL way so that millisecond decimals are preserved as well, using:
SELECT EXTRACT(EPOCH FROM TIMESTAMP WITH TIME ZONE '2019-02-11 08:01:33.423+00'); // 1549872093.423
But I am not able to integrate it into a function and it gives following error:
syntax error at or near "t1"
LINE 5: ...ELECT EXTRACT(EPOCH FROM TIMESTAMP WITH TIME ZONE t1) into t..
CREATE or REPLACE FUNCTION getMSFromTime2(t1 timestamp with time zone)
RETURNS bigint AS $$
declare time1 double precision ;
BEGIN
SELECT EXTRACT(EPOCH FROM TIMESTAMP WITH TIME ZONE t1) into time1;
return time1;
END;
$$ LANGUAGE plpgsql;
Please suggest a way so as to create a PostgreSQL function which can do this functionality.
extract() returns a double value that represents seconds, by casting that to a bigint you lose the fractional seconds (=milliseconds)
If you want a bigint representing milliseconds, you need to multiple the result with 1000.
There is also no reason to use PL/pgSQL for such a simple thing:
CREATE or REPLACE FUNCTION getmsfromtime(t1 timestamp with time zone)
RETURNS bigint
AS $$
SELECT (EXTRACT(EPOCH FROM t1)*1000)::bigint;
$$
LANGUAGE sql;
I'm new to pl/pgsql and I'm trying to execute following function and it gives 0 records as result.
CREATE OR REPLACE FUNCTION public.detectselect (i_channelID integer,te_startTime text,te_endTime text)
RETURNS SETOF detect_inst AS $BODY$
declare
r detect_inst%rowtype;
tstz_endTime timestamp without time zone;
tstz_startTime timestamp without time zone;
BEGIN
tstz_endTime = to_timestamp(te_endTime,'DD/MM/YYYY hh24:mi:ss')::timestamp without time zone;
tstz_startTime = to_timestamp(te_startTime,'DD/MM/YYYY hh24:mi:ss')::timestamp without time zone;
for r in SELECT * FROM detect_inst d WHERE d."ChannelID" = i_channelID AND d."EndTime" >= tstz_startTime AND d."EndTime" < tstz_endTime loop
return next r;
end loop;
RETURN;
END;
$BODY$ LANGUAGE plpgsql;
call as
select detectselect(1,'2016-01-21 0:0:0','2016-01-23 0:0:0');
but it give correct results when i give static time stamp values in this way
CREATE OR REPLACE FUNCTION public.detectselect (i_channelID integer,te_startTime text,te_endTime text)
RETURNS SETOF detect_inst AS $BODY$
declare
r detect_inst%rowtype;
tstz_endTime timestamp without time zone;
tstz_startTime timestamp without time zone;
BEGIN
tstz_endTime = to_timestamp(te_endTime,'DD/MM/YYYY hh24:mi:ss')::timestamp without time zone;
tstz_startTime = to_timestamp(te_startTime,'DD/MM/YYYY hh24:mi:ss')::timestamp without time zone;
for r in SELECT * FROM detect_inst d WHERE d."ChannelID" = i_channelID AND d."EndTime" >= '2016-01-21 0:0:0' AND d."EndTime" < '2016-01-23 0:0:0' loop
return next r;
end loop;
RETURN;
END;
$BODY$ LANGUAGE plpgsql;
Your function is overly complex. You don't need PL/pgSQL and you don't need a (slow) cursor to return the result.
It can be simplified to a plain SQL function which also will be a lot faster:
CREATE OR REPLACE FUNCTION public.detectselect (i_channelID integer, te_startTime timestamp, te_endTime timestamp)
RETURNS SETOF detect_inst AS
$BODY$
SELECT *
FROM detect_inst d
WHERE d."ChannelID" = i_channelID
AND d."EndTime" >= te_starttime
AND d."EndTime" < te_endtime
$BODY$
LANGUAGE sql;
You then call it:
select *
from detectselect(1, timestamp '2016-01-21 00:00:00', timestamp '2016-01-23 00:00:00' );
You should also avoid those dreaded quoted identifiers. They are much more trouble then they are worth it
I want to see the result displaying dates like this
"2001-01-01 00:00:00+05:30"
"2001-01-02 00:00:00+05:30"
"2001-01-03 00:00:00+05:30"
"2001-01-04 00:00:00+05:30"
"2001-01-05 00:00:00+05:30"
"2001-01-06 00:00:00+05:30"
"2001-01-07 00:00:00+05:30"
so on...
but iam getting error
ERROR: query has no destination for result data
HINT: If you want to discard the results of a SELECT, use PERFORM instead.
CONTEXT: PL/pgSQL function insert_date_dimension(date) line 12 at SQL statement
can you tell me what is the issue
function i created
create or replace function insert_date_dimension("Date" date)
returns text as
$$
Declare dat date;
start_date date;
end_date date;
Begin
start_date:='2016/01/01';
end_date:='2016/12/31';
while start_date<=end_date
loop
select start_date;
start_date:=start_date+ interval '1 day';
End loop;
return start_date;
end;
$$
LANGUAGE 'plpgsql';
can you tell me what is the issue with this function i was not able to execute it.I want to take all the column in select statment..please tell me create or replace function insert_date_dimension("date" date)
returns setof date as $$
declare
dat date;
start_date date;
end_date date;
begin
start_date := '2016/01/01';
end_date := '2016/12/31';
while start_date <= end_date loop
--return next start_date;
select start_date,date_part('week',start_date),date_part('quarter',start_date),to_char(start_date, 'day'),to_char(start_date, 'month'),
extract(year from current_date),extract(month from current_date);
start_date:= start_date + interval '1 day';
end loop;
end;
$$ language plpgsql;
ERROR: query has no destination for result data
HINT: If you want to discard the results of a SELECT, use PERFORM instead.
CONTEXT: PL/pgSQL function insert_date_dimension(date) line 11 at SQL statement
********** Error **********
No need for a user defined function. Just use generate_series:
select generate_series('2016/01/01'::date, '2016/12/31', '1 day');
But if you are just fiddling with plpgsql then return next a setof date
create or replace function insert_date_dimension("date" date)
returns setof date as $$
declare
dat date;
start_date date;
end_date date;
begin
start_date := '2016/01/01';
end_date := '2016/12/31';
while start_date <= end_date loop
return next start_date;
start_date := start_date + interval '1 day';
end loop;
end;
$$ language plpgsql;
plpgsql is an identifier. Do not quote it.
I am stuck in subtracting now() with modified date in pgsql trigger function.
This is my query,
CREATE OR REPLACE FUNCTION trigger_cust_order_mst_after_update()
RETURNS trigger AS
$BODY$
declare
v_log_max_ldate timestamp;
v_time time;
BEGIN
v_log_max_ldate = (select max(d_Ldate ) from cust_order_log where n_ord_srno = new.n_srno);
v_time = now() - v_log_max_ldate;
when this trigger executes,an error occurs as,
ERROR: invalid input syntax for type date: "1"
CONTEXT:PL/PgSQL function trigger_cust_order_mst_after_update()
Please help me out from this.