I am trying to create a function which accepts two arrays, and a date. The function uses the date
in a way where I want hardcoded values of time (with timezone) which are already stated in the function body (in the orig_dataset CTE). Here is my function so far:
CREATE or replace FUNCTION f_loop_in_lockstep_final(_id_arr int[], _counter_arr int[], d_date date)
RETURNS TABLE (uc_name_ varchar)
LANGUAGE plpgsql AS
$func$
DECLARE
_id int;
_counter int;
d_date date;
BEGIN
FOR _id, _counter IN
SELECT *
FROM unnest (_id_arr, _counter_arr) t
LOOP
RETURN QUERY
with orig_dataset as (
select routes
from campaign_routes cr
where cr.created_at between 'd_date 06:00:00 +05:00' and 'd_date 18:00:00 +05:00'
)
-- a couple of further CTE's result in a final CTE called final_cte
select * from final_cte;
END LOOP;
END
$func$;
When I use the following function call:
SELECT * FROM f_loop_in_lockstep_final('{454,454}'::int[]
, '{2,3}'::int[], to_date('2023-01-17','YYYY-MM-DD'));
I receive the following error:
SQL Error [22007]: ERROR: invalid input syntax for type timestamp with time zone: "d_date 06:00:00 +05:00"
Where: PL/pgSQL function f_loop_in_lockstep_final(integer[],integer[],date) line 14 at RETURN QUERY
Well, obviously 'd_date 06:00:00 +05:00' is not a valid date literal.
You need to add a time value to the variable to create a timestamp value based on that:
where cr.created_at between d_date + '06:00:00 +05:00'::time
and d_date + '18:00:00 +05:00'::time
I am not entirely sure that using a time zone offset in a time constant works correctly, so maybe you need:
where cr.created_at between ((d_date + '06:00:00'::time) at time zone '+05:00')
and ((d_date + '18:00:00'::time) at time zone '+05:00')
Related
I have a function call like :
SELECT * FROM f_loop_in_lockstep_final('{454,454}'::int[]
, '{2,3}'::int[], to_date('2023-01-17','YYYY-MM-DD'));
I have declared funtion as :
CREATE or replace FUNCTION f_loop_in_lockstep_final(_id_arr int[], _counter_arr int[], d_date date)
In the function body I have written the following where clause (simplified):
select * from routes where
routes.time_created between ((d_date::date + '11:59:00'::time) at time zone '+05:00') and ((d_date::date + '18:00:00'::time) at time zone '+05:00')
This is giving a null result set (although no errors are displayed), whereas I know for sure that it should be non null result set.
P.S - Here is the simplified code of my function:
CREATE or replace FUNCTION f_loop_in_lockstep_final(_id_arr int[], _counter_arr int[], d_date date)
RETURNS TABLE (uc_name_ varchar)
LANGUAGE plpgsql AS
$func$
DECLARE
_id int;
_counter int;
d_date date;
BEGIN
FOR _id, _counter IN
SELECT *
FROM unnest (_id_arr, _counter_arr) t
LOOP
RETURN QUERY
with orig_dataset as (
select routes
from campaign_routes cr
where cr.created_at between ((d_date::date + '11:59:00'::time) at time zone '+05:00') and ((d_date::date + '18:00:00'::time) at time zone '+05:00')
)
-- a couple of further CTE's result in a final CTE called final_cte
select * from final_cte;
END LOOP;
END
$func$;
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'm building this function:
CREATE OR REPLACE FUNCTION qradar21(cliente_in VARCHAR(50), fecha_inicio timestamp, fecha_fin timestamp) RETURNS TABLE(empresa varchar, fecha timestamp, fuente text, total float) AS $$
BEGIN
RETURN QUERY
SELECT qradar_eventos_detalle.empresa, qradar_eventos_detalle.fecha, eventos->>'fuente' AS fuente, sum((eventos->>'total')::float) AS total FROM public.qradar_eventos_detalle
WHERE qradar_eventos_detalle.empresa = 'cliente_in'
AND qradar_eventos_detalle.fecha BETWEEN 'fecha_inicio' AND 'fecha_fin'
GROUP BY qradar_eventos_detalle.empresa, qradar_eventos_detalle.fecha, qradar_eventos_detalle.eventos
ORDER BY total DESC;
END;
$$ LANGUAGE plpgsql
And calling it with:
SELECT * FROM qradar21('BancoXXX', '2018-12-29 12:00:00', '2019-03-03 07:00:00');
Getting this message:
ERROR: invalid input syntax for type timestamp: «fecha_inicio»
LINE 3: AND qradar_eventos_detalle.fecha BETWEEN 'fecha_inicio' A...
If I change the function to use directly the date (AND qradar_eventos_detalle.fecha BETWEEN '2018-12-29 12:00:00' AND '2018-12-30 07:00:00'), it works great.
I don't know what I'm doing wrong... Does anyone know how to pass this "timestamp without time zone" format to the function?
Thank you in advance
Your function uses string literals, rather then referencing the parameters.
You need to remove the single quotes around your parameter names:
WHERE qradar_eventos_detalle.empresa = cliente_in --<< no quotes here!
AND qradar_eventos_detalle.fecha BETWEEN fecha_inicio AND fecha_fin
^
or here
When you call it, it's also better to use proper timestamp literal:
SELECT *
FROM qradar21('BancoXXX', timestamp '2018-12-29 12:00:00', timestamp '2019-03-03 07:00:00');
I was trying to call the function I created to fetch some data for particular time slot. Given below is a script of my function:
CREATE OR REPLACE FUNCTION my_function(
starttime timestamp with time zone,
endtime timestamp with time zone)
RETURNS TABLE("Deviceid" integer, "AlertTime" timestamp with time zone)
LANGUAGE 'plpgsql'
COST 100.0
AS $function$
DECLARE
r record;
BEGIN
SELECT "DeviceID" , "AlertTime" FROM my_table
WHERE "AlertTime" BETWEEN starttime AND endtime;
END;
$function$;
ALTER FUNCTION public.my_function(timestamp with time zone, timestamp with time zone)
OWNER TO postgres;
When I am calling function with time '2016-12-15 00:00:01' to '2016-12-15 18:00:00' I am not getting any record. Even many records available for the time slot, I checked it by passing same time values for the query inside the function, its fetching data properly.
select * from my_function('2016-12-14 00:00:01','2016-12-15 18:00:00')
But when I am calling function with 2016-12-15 00:00:00' to '2016-12-15 18:00:00' I am able to get all records.
select * from my_function('2016-12-14 00:00:00','2016-12-15 18:00:00')
Even I tried to change the input parameters to "character varying" and convert the input internally to time stamp even then it is not working.
The explanation is obvious, isn't it?
All the matching rows from mytable have "AlertTime" greater or equal than 2016-12-14 00:00:00 and less than 2016-12-14 00:00:01.
I know how to convert a text to timestamp in postgreSQL using
SELECT to_timestamp('05 Dec 2000', 'DD Mon YYYY')
but how can I convert a text variable (inside a function) to timestamp??
In my table (table_ebscb_spa_log04) "time" is a character varying column, in which I have placed a formated date time (15-11-30 11:59:59.999 PM).
I have tried this function, in order to convert put the date time text into a variable (it always change) and convert it into timestamp...
CREATE OR REPLACE FUNCTION timediff()
RETURNS trigger AS
$BODY$
DECLARE
timeascharvar character varying;
timeastistamp timestamp;
BEGIN
IF NEW.time_type = 'Lap' THEN
SELECT t.time FROM table_ebscb_spa_log04 t INTO timeascharvar;
SELECT to_timestamp('timeascharvar', 'yy-mm-dd HH24:MI:SS.MS') INTO timeastistamp;
END IF;
RETURN timeastistamp;
END
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION timediff()
OWNER TO postgres;
but whenever I run it in the table, it shows this ERROR message...
It seems that "to_timestamp" waits for a number to be the year, how can I get it to recognize the variable as if it were numbers?
The first parameter to to_timestamp should be your var not a string containing the name of your var:
to_timestamp(timeascharvar, 'yy-mm-dd HH24:MI:SS.MS')