I have a procedure in PostgreSQL that I want to add the number of minutes to CURRENT_TIMESTAMP like below
timestamp_var := CURRENT_TIMESTAMP + interval '20 minutes';
But the number of minutes is a parameter.
Do we have the functions to do this?
Pls help me in this case
CREATE OR REPLACE FUNCTION modify_time(id users.id%TYPE, min integer) AS $$
BEGIN
UPDATE
users
SET
modified_at = CURRENT_TIMESTAMP
WHERE
user_id = id;
END
$$ LANGUAGE plpgsql;
I want to add min minutes to CURRENT_TIMESTAMP
thanks
You can multiply intervals by integers. The following gives you a timestamp 20 minutes in the future:
select current_timestamp + (20 * interval '1 minute')
Or, as murison mentions in another answer to this question, there is a more succinct way to express this:
select current_timestamp + (20 ||' minutes')::interval
So, your code could look like:
CREATE OR REPLACE FUNCTION modify_time(id users.id%TYPE, min integer) AS $$
BEGIN
UPDATE
users
SET
modified_at = CURRENT_TIMESTAMP + (min * interval '1 minute')
WHERE
user_id = id;
END
$$ LANGUAGE plpgsql;
the other way is
select current_timestamp + (20 ||' minutes')::interval
If You need half minute or secounds :
SELECT current_timestamp + (50 * interval '1 seconds');
Related
I have a simple Postgres function:
CREATE OR REPLACE FUNCTION public.drivers_have_unsatisfied_documents()
RETURNS driver_expiring_documents
AS $function$
DECLARE
unsatified_documents driver_expiring_documents;
expiring_doc driver_expiring_documents%rowtype;
expiring_doc_driver_ids text[];
expired_doc_driver_ids text[];
expiring_date date;
driver_id_arg text;
BEGIN
unsatified_documents := array(
select expiration_date, driver_id from all_requirements_driver_documents where expiration_date <= (now() + interval '1 month')::DATE and expiration_date > (now() - interval '7 day')::DATE
union
select expiration_date, driver_id from all_requirements_vehicle_documents where expiration_date <= (now() + interval '1 month')::DATE and expiration_date > (now() - interval '7 day')::DATE
);
-- Do some more stuff, code intentionally removed ---
return unsatified_documents;
end;
$function$ stable language 'plpgsql';
This is throws error saying
multiple columns in subquery
Can someone please help me fix it?
I am trying to write a function that returns random start time (it must be between now and a week long) and an endtime. I wrote this function:
CREATE OR REPLACE FUNCTION random_start_end_time(n integer)
RETURNS TABLE (startime TIMESTAMP WITH TIME ZONE, endtime TIMESTAMP WITH TIME ZONE)
LANGUAGE 'plpgsql'
AS $BODY$
BEGIN
RETURN QUERY
SELECT NOW() + (random() * (NOW()+'7 days' - NOW())) as startime;
SELECT NOW() + (random() * (NOW()+'7 days' - NOW())) as endtime;
END;
$BODY$
I can't find out how to generate multiple columns. For example I want n=100 columns of random start time and end time to be generated.
In general I can't understand how I can fill an empty table (with this function I am going to fill a table later).
Any thoughts would be valuable.
Thank you.
Use RETURN NEXT to add a row to the result set of a table function and RETURN to end the function execution. You also have to decide if you want a function that returns two columns or two rows. Your case looks like you want to do something like:
CREATE OR REPLACE FUNCTION random_start_end_time(
OUT starttime TIMESTAMP WITH TIME ZONE,
OUT endtime TIMESTAMP WITH TIME ZONE
) RETURNS record
LANGUAGE sql AS
$BODY$
WITH start AS (
SELECT current_timestamp + random() * INTERVAL '7 days' as starttime
)
SELECT starttime,
starttime + random() * INTERVAL '7 days' as endtime
FROM start;
$BODY$;
Call it like
SELECT * FROM random_start_end_time();
If you really want to return several rows, that would be
CREATE OR REPLACE FUNCTION random_start_end_time()
RETURNS SETOF timestamp with time zone
LANGUAGE plpgsql AS
$BODY$
BEGIN
RETURN NEXT current_timestamp + random() * INTERVAL '7 days';
RETURN NEXT current_timestamp + random() * INTERVAL '7 days';
RETURN; /* end the function */
END;
$BODY$;
I've got a plpgsql function. I need to take the date 5 days from today, and then divide month into "fives" to takte the start of "last five". The problem is thay make_date does not exist in the posgres version that is used on the server....
create or replace function getFirstDayOfFive()
returns timestamp with time zone as $$
declare
firstDay timestamp;
startOp timestamp;
begin
startOp = now() - interval '5 day';
SELECT
make_date(
date_part('year', startOp)::int,
date_part('month', startOp)::int,
greatest(
floor(date_part('day', startOp) / 5) * 5,
1
)::int
)
INTO firstDay;
RETURN firstDay;
end;
$$
language plpgsql;
It worked fine last week, but now I got an error when I call it
ERROR: BŁĄD: function make_date(integer, integer, integer) does not exist
LINE 2: make_date(
^
HINT: There is no function matching provided name and arguments. Maybe you should cast data.
QUERY: SELECT
make_date(
date_part('year', startOp)::int,
date_part('month', startOp)::int,
greatest(
floor(date_part('day', startOp) / 5) * 5,
1
)::int
)
CONTEXT: PL/pgSQL function "getfirstdayoffive" line 7 at wyrażenie SQL
SQL state: 42883
What happened that earlier it worked and now it gives error?
[Edit]
I found out that make_date is available from postgresQL 9.4, but on the server there is posthresQL 9.1 is there any way to do the same in this old version od DB? I'm trying to replace the make_date with something like
create or replace function getFirstDayOfFive()
returns timestamp with time zone as $$
declare
firstDay timestamp;
startOp timestamp;
begin
startOp = now() - interval '5 day';
SELECT
date to_char(startOp, 'YYYY-MM-')||to_char(greatest(
floor(date_part('day', startOp) / 5) * 5,
1
)::int)
INTO firstDay;
RETURN firstDay;
end;
$$
language plpgsql;
I think you can simplify this by simply adding the desired number of days to the start of the month. Apparently you only want a date so I would also recommend to change the return type to date
create or replace function getfirstdayoffive()
returns date
as
$$
select date_trunc('month', current_date - 5)::date
+ (greatest(floor(extract(day from current_date - 5) / 5) * 5, 1))::int - 1;
$$
language sql
stable;
Is there any function(s) in postgres equivalent to Oracle function LAST_DAY().
I need to get last day in postgres (including month and year)
Well, In postgres, it seems there's no such function equivalent to LAST_DAY() available in oracle.
If you need to, you can have your own in the following ways as a
Select Query
SELECT (date_trunc('MONTH', now()) + INTERVAL '1 MONTH - 1 day')::date;
plsql Function
CREATE OR REPLACE FUNCTION last_day(date)
RETURNS date AS
$$
SELECT (date_trunc('MONTH', $1) + INTERVAL '1 MONTH - 1 day')::date;
$$ LANGUAGE 'sql'
IMMUTABLE STRICT;
Hope this helps.
create or replace funCtion last_day(fromdt anyelement)
returns date as
$BODY$
SELECT (date_trunc('MONTH', cast(fromdt as date)) + INTERVAL '1 MONTH - 1 day')::date;
$BODY$
LANGUAGE sql VOLATILE
COST 100;
ALTER FUNCTION last_day(anyelement)
OWNER TO postgres;
I want update a column by adding days to current time. In pseudosyntax it would be:
UPDATE foo
SET time = current_timestamp + days::integer
days is a column in the same table.
select now() + cast('1 day' as interval) * 3 -- example: 3 days
create function add_days_to_timestamp(t timestamptz, d int)
returns timestamptz
as
$$
begin
return t + interval '1' day * d;
end;
$$ language 'plpgsql';
create operator + (leftarg = timestamptz, rightarg = int,
procedure = add_days_to_timestamp);
Now this would work:
update foo set time = current_timestamp + 3 /* day variable here,
or a column from your table */
Note:
for some reason, adding an integer to date is built-in in Postgres, this would work:
select current_timestamp::date + 3 -- but only a date
this would not(unless you define your own operator, see above):
select current_timestamp + 3
calculatedDate timestamp without time zone;
calculatedDate := current_timestamp + interval '1' day * days_count;