procedure type date IN param postgresql - postgresql

I want to know how I can enter a parameter within a function type date since at the time of doing so, the following error
report_soat(date, date)
Undefined function: 7 ERROR: operator does not exist: date >= character varying LINE 6: BETWEEN fecha_in AND fecha_out ^ HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts. QUERY: SELECT soats.status AS "estado", soats.placa AS "placa" FROM soats where soats.task_id IS NOT NULL and date(soats.created) BETWEEN fecha_in AND fecha_out CONTEXT: PL/pgSQL function report_soat(character varying,character varying) line 2 at RETURN QUERY
SELECT
soats.status AS "estado",
soats.placa AS "placa"
FROM soats
where soats.task_id IS NOT NULL and date(soats.created)
BETWEEN start_date AND end_date;
IN start_date date, IN end_date date, OUT status varchar, OUT placa
varchar

Try...
report_soat('2017-11-14'::date, '2017-11-14'::date)

Related

How to run a "returns void" function with JSON parameter?

This function created as
CREATE OR REPLACE FUNCTION myschema._add1( vjson json, vtype smallint, vdate date)
returns void language 'plpgsql' cost 100 volatile security definer set search_path=myschema
as $$
begin
insert into myschema.tbl(cjson, ctype, cdate)
values(vjson, vtype, vdate);
end;
$$
Tbl definition:
create table myschema.tbl(cjson json, ctype smallint, cdate date)
Running the function
select myschema._add1('{"j":["j1", "j2"]}', 1, '2021-02-26') get
ERROR: function myschema._add1hidoc(unknown, integer, unknown) does not
exist HINT: No function matches the given name and argument types.
you might need to add explicit type casts.
select myschema._add1('{"j":["j1", "j2"]}'::json, 1, '2021-02-26'::date) get
ERROR: function myschema._add1hidoc(json, integer, date) does not
exist HINT: No function matches the given name and argument types.
you might need to add explicit type casts.
The only parameter you did not cast explicitly was the smallint parameter, but I am sure, that's the problem. I tried in the fiddle and it worked, after casting only the int to smallint:
select _add1('{"j":["j1", "j2"]}', 1::smallint, '2021-02-26')

Returning Table with null value causes error

I have a simple function that has optional parameters. When I leave out a parameter, which should just default to null, I get an error that it is not an integer.
Here is the function:
CREATE FUNCTION rewrite(_postid integer DEFAULT NULL::integer,
_url character varying DEFAULT NULL::character varying)
RETURNS TABLE
(
PostTypeID integer,
DestinationURL varchar,
)
LANGUAGE plpgsql
AS
$function$
BEGIN
RETURN QUERY
SELECT
NULL AS PostTypeID,
_url AS DestinationURL,
FROM reference.destinations dest1
WHERE length(TRIM(dest1.DestinationURL)) > 0
AND _url LIKE '%' || TRIM(dest1.DestinationURL)) || '%'
ORDER BY length(dest1.DestinationURL)) DESC
LIMIT 1;
END;
$function$
If I run SELECT * FROM utility.rewrite(_url := 'wikipedia.org') then I get this error:
[42804] ERROR: structure of query does not match function result type
Detail: Returned type text does not match expected type integer in
column 1.
So column1 must be the PostTypeID column in my RETURNS TABLE definition. But I am selecting NULL AS PostTypeID so why is it not just returning NULL?
If I run SELECT * FROM utility.rewrite(_postid = 0, _url := 'wikipedia.org') then it works fine. But I don't want 0 to be returned, I want NULL.
Just because you use the alias posttypeid in the query does not mean that PostgreSQL infers the data type of your PL/pgSQL variable.
Even though NULL can be any data type, PostgreSQL has to determine a data type for the result column of the query. Lacking other information, it arbitrarily chooses text.
Mapping the query result type to the function result type happens later, in PL/pgSQL. That is what causes the error you observe.
You can avoid the problem by specifying the type of NULL with an explicit type cast:
SELECT CAST (NULL AS integer)

error raise when use within GROUP with string_agg in postgresql

My query in postgresql 10, raises an error when it uses within GROUP clause
ERROR: function string_agg(character varying, unknown, integer) does
not exist
I have tables at and atrelation. at has unique id and description while atrelation stores multiple transaction with code of related at and transaction line id. for example
product row with id 6 has a column name tag has value service5% and contco4.5%
product row with id 5 has tag value service5%
I need to show 2-rows i.e row 6 and 5.
row 5 show the column tag value 'service5% and contco4.5% '
row 6 show the column tag value 'service5%'
select atrelation.id,
string_agg(at.description, ' and ' ) within GROUP (ORDER BY atrelation.id ) as tag1
from at, atrelation
where atrelation.id = atrelation.atid
group by atrelation.id
order by atrelation.id desc;
above query raise following error,
ERROR: function string_agg(character varying, unknown, integer) does not exist
LINE 1: select atrelation.purchase_order_line_id as id, string_agg(a...
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
********** Error **********
ERROR: function string_agg(character varying, unknown, integer) does not exist
SQL state: 42883
Hint: No function matches the given name and argument types. You might need to add explicit type casts.
Character: 49
You need to put the ORDER BY into the function call and remove the WITHIN GROUP part:
string_agg(at.description, ' and ' ORDER BY atrelation.id) as tag1

pl/pgSQL - Proper data for parameter used in "WHERE IN" clause?

I am attempting to create a PL/pgSQL function that accepts an array/list of values (properties) that will be used for filtering records using an "IN" clause.
CREATE OR REPLACE FUNCTION ticket.property_report(start_date DATE, end_date DATE, properties VARCHAR[]) RETURNS
TABLE(total_labor_mins numeric(10,2), total_parts_cost numeric(10,2), ticket_count bigint, property VARCHAR(6)) AS $$
BEGIN
RETURN QUERY SELECT SUM(c.total_labor_mins), SUM(c.total_parts_cost), COUNT(*) as ticket_count, t.property_id as property
FROM ticket.ticket AS t LEFT JOIN ticket.ticket_cost_row AS c ON t.id = c.ticket_id
WHERE t.property_id IN (properties) AND t.open_date >= start_date AND t.open_date <= end_date
GROUP BY t.property_id;
END;
$$ LANGUAGE plpgsql;
However, I am struggling with what type of data type to use in the parameter list. A single "varchar" is not appropriate as there could be many property values. However, whenever I use an array (as in the code above), I received the following message:
SELECT ticket.property_report(TO_DATE('2019-01-01', 'yyyy-MM-dd'), TO_DATE('2019-12-31', 'yyyy-MM-dd'), '{"5305"}');
ERROR: operator does not exist: character varying = character varying[]
LINE 3: WHERE t.property_id IN (properties) AND t.open_date >=...
^
HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts.
QUERY: SELECT SUM(c.total_labor_mins), SUM(c.total_parts_cost), COUNT(*) as ticket_count, t.property_id as property
FROM ticket.ticket AS t LEFT JOIN ticket.ticket_cost_row AS c ON t.id = c.ticket_id
WHERE t.property_id IN (properties) AND t.open_date >= start_date AND t.open_date <= end_date
GROUP BY t.property_id
CONTEXT: PL/pgSQL function ticket.property_report(date,date,character varying[]) line 3 at RETURN QUERY
What is the property data type to use for this purpose. In example, something that would translate to WHERE t.property_id IN ('123','12','1',...)?
Thanks.
The array is the correct data type, you just need to use an operator that works with that:
WHERE t.property_id = ANY (properties)

error 'function sum(character varying) does not exist' using sum with SQL Alchemy and Postgres [duplicate]

I want to calculate the average number from a column in PostgreSQL
SELECT AVG(col_name)
From TableName
It gives me this error:
ERROR: function avg (character varying) does not exist
LINE 1: SELECT AVG(col_name)
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
Store numbers in a numeric field, an integer, decimal or whatever. But not in a text/varchar field.
Check the manual for all numeric data types.
Nasty workaound: CAST some records to a numeric value and keep others as text. Example:
/*
create temp table foo AS
SELECT x FROM (VALUES('x'),('1'),('2')) sub(x);
*/
WITH cte AS (
SELECT
CASE
WHEN x ~ '[0-9]' THEN CAST(x AS decimal) -- cast to numeric field
END AS num,
CASE
WHEN x ~ '[a-zA-Z]' THEN x
END AS a
FROM foo
)
SELECT AVG(num), COUNT(a) FROM cte;