postgres interval add variable current_setting not work - postgresql

set session myconstants.test = '10';
set session myconstants.testb = '10 min';
SELECT now()::time - interval concat (current_setting('myconstants.selfName')::varchar,' min');
SELECT now()::time - INTERVAL '10 min';
set session myconstants.test = '10';
SELECT now()::time - interval current_setting('myconstants.testb')::varchar;
SELECT now()::time - INTERVAL '10 min';
i want add variable in interval function,but current_setting not work..how could i solve it?i use postgres

You need to cast the variable value to an interval:
SELECT now()::time - current_setting('myconstants.testb')::interval
The prefix notation interval '....' only works with constants following it.

You can also try make_interval.
SET session myconstants.test = 10;
SELECT
now() + make_interval(mins => current_setting('myconstants.test')::int);

i found this solution,operator does not exist: timestamp with time zone + integer in PostgreSql.
create function addit(timestamptz,int) returns timestamptz immutable language sql as $$
select $1+ interval '1 hour'*$2
$$;
create operator + (leftarg =timestamptz, rightarg =int, procedure=addit);
create function minusit(timestamptz,int) returns timestamptz immutable language sql as $$
select $1+ interval '-1 hour'*$2
$$;
create operator - (leftarg =timestamptz, rightarg =int, procedure=minusit);
create + and - operator ,and execute
set session myconstants.testb = -1;
select start_time ,start_time - current_setting('myconstants.testb')::integer from besoccer_team bt ;
select start_time ,start_time - current_setting('myconstants.testb')::integer from besoccer_team bt ;
start_time is timestamp type
set session myconstants.testb = -1;
select now()::timestamp , now()::timestamp - current_setting('myconstants.testb')::integer from besoccer_team bt ;
select now()::timestamp , now()::timestamp - current_setting('myconstants.testb')::integer from besoccer_team bt ;

Related

postgres procedure giving ERROR: invalid input syntax for type timestamp: "select CURRENT_TIMESTAMP - INTERVAL '7 day'"

I have created postgres procedure, I am not writing whole procedure here, Just writing the part which is giving error as belows,
create or replace procedure xyz() as $$
declare
v_time timestamp without time zone;
v_retain_days int;
Begin
select retain_days from abc into v_retain_days;
v_time := cast('select CURRENT_TIMESTAMP - INTERVAL ''' || v_retain_days || ' day''' as timestamp) ;
END;
With this procedure call, Its giving error as below:
ERROR: invalid input syntax for type timestamp: "select CURRENT_TIMESTAMP - INTERVAL '7 day'"
Can anyone help in this?
No need for a SELECT, dynamic SQL, casting or string concatenation:
v_time := CURRENT_TIMESTAMP - INTERVAL '1 day' * v_retain_days;
or alternatively:
v_time := CURRENT_TIMESTAMP - make_interval(days => v_retain_days);

How can i create n columns in postgresql?

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$;

Add minutes to CURRENT_TIMESTAMP in PostgreSQL

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');

LAST_DAY function in postgres

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;

Adding sum of current_timestamp and days column in 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;