How to get the result parameter of a NativeQuery - postgresql

I want to make this Query:
Select
srid,
substring(srtext
from (position('DATUM["' in srtext)+7)
for (position('ID["' in srtext)+2)
- (position('DATUM["' in srtext)+7))
from spatial_ref_sys
order by substring
So, I create a
Query query = em().createNativeQuery(QUERY)
Also create a Srid object that has a Long srid and a String sridText.
I need to get those values and put into a List.
The substring on sridText, and obviously the srid into Long srid.
Please help!!!

Found the answer. First of all, I did a plpgsql function called getSrid
CREATE OR REPLACE FUNCTION getSRID() returns text[] as $$
declare
resultado text[];
consulta cursor for
Select srid,substring(srtext from (position('DATUM["' in srtext)+7)
for(position('ID["' in srtext)+2)
- (position('DATUM["' in srtext)+7)) as sub
from spatial_ref_sys;
cont int;
i int;
sridd int;
srTextt text;
begin
open consulta;
i=1;
EXECUTE 'SELECT COUNT(*) FROM SPATIAL_REF_SYS' into cont;
resultado := ARRAY[cont];
while(i<cont) loop
fetch consulta into sridd,srTextt;
resultado[i] := sridd;
resultado[i+1] := srTextt;
i:=i+2;
end loop;
return resultado;
end
$$ language plpgsql;
As you see I got a Text[] on return so in my java call I cast the object to String[]:
public List<SridDTO> listaa(){
int i = 0;
List<SridDTO> list = new ArrayList<SridDTO>();
Query query = em().createNativeQuery("Select getSrid()");
String[] vector = (String[]) query.getSingleResult();
while(i<vector.length){
SridDTO sridDTO = new SridDTO(new Long(vector[i]),vector[i+1]);
i = i + 2;
list.add(sridDTO);
}
return list;
}

Related

How to combine custiom defined variables and display them as records of a table in postgres

I'm a beginner in plpgsql and working on a project which requires me to write a function that returns two variables in the form of 2 columns (res,Result). I've done a quite a bit of searching but didn't find answer for the same. The reference to my code is below
CREATE OR REPLACE FUNCTION propID(character varying)
RETURNS SETOF RECORD AS $val$
DECLARE
t_row record;
res BOOLEAN;
result character varying;
value record;
BEGIN
FOR t_row IN SELECT property_id FROM property_table WHERE ward_id::TEXT = $1 LOOP
RAISE NOTICE 'Analyzing %', t_row;
res := false; -- here i'm going to replace this value with a function whos return type is boolean in future
result := t_row.property_id;
return next result; --here i want to return 2 variables (res,result) in the form of two columns (id,value)
END LOOP;
END;
$val$
language plpgsql;
Any help on the above query would be very much appreciated.
Assuming that property_id and ward_id are integers you can achieve your goal in a simple query like this:
select some_function_returning_boolean(property_id), property_id
from property_table
where ward_id = 1; -- input parameter
If you absolutely need a function, it can be an SQL function like
create or replace function prop_id(integer)
returns table (res boolean, id int) language sql
as $$
select some_function_returning_boolean(property_id), property_id
from property_table
where ward_id = $1
$$;
In a plpgsql function you should use return query:
create or replace function prop_id(integer)
returns table (res boolean, id int) language plpgsql
as $$
begin
return query
select some_function_returning_boolean(property_id), property_id
from property_table
where ward_id = $1;
end
$$;

Push result of each query into array

I've created function:
CREATE FUNCTION citiesById(integer[]) RETURNS text[] AS
$$
DECLARE
element int;
result text[];
BEGIN
FOREACH element IN ARRAY $1
LOOP
WITH t1 as (SELECT city FROM cities WHERE id = element)
SELECT city FROM t1 INTO result;
END LOOP;
RETURN result;
END
$$
LANGUAGE plpgsql;
I'm trying to execute queries in a loop and insert result of each query into array to get something like ['London', 'Paris', 'Moscow']. But I'm getting an error:
Is there a correct way to do that?
CREATE FUNCTION citiesById(integer[]) RETURNS text[] AS
$$
DECLARE
element int;
result text[];
BEGIN
FOREACH element IN ARRAY $1
LOOP
result := array_append(result, (SELECT city FROM cities WHERE id = element)::text);
END LOOP;
RETURN result;
END
$$
LANGUAGE plpgsql;

How get row count from return type in postgres?

I have a function that return a table (my customer type).
How I can get row count of return object?
CREATE TYPE observer_holder AS ("CustomerName" TEXT,"CustomerFamily" TEXT)
CREATE OR REPLACE FUNCTION getItem(i_callStateText TEXT, i_maxText TEXT)
RETURNS SETOF observer_holder
LANGUAGE plpgsql
AS $$
declare
sendOffset INTEGER;
fetchRecord RECORD;
result observer_holder;
runQuery2 BOOLEAN := lower(trim(both ' ' from i_callStateText)) ='notnull' AND (position('::tsrange' in i_maxText) < 1);
query1 TEXT := '...';
query2 TEXT := '...';
BEGIN
FOR fetchRecord IN EXECUTE CASE WHEN runQuery2 THEN query2 ELSE query1 END LOOP
result."CustomerFamily" := customerRecord.family;
result."CustomerName" := customerRecord.name;
.
.
.
RETURN next result;
END LOOP;
-- my question , how get result count?
RAISE notice 'row count: %', length(result::observer_holder); >> Exception
RETURN;
END; $$;
I need result row count. Please help me.

How to run SELECT queries in PL/pgSQL IF statements

I am trying to run SELECT queries in PL/pgSQL IF statements using the code below:
DO
$do$
DECLARE
query_type real;
arr real[] := array[1];
BEGIN
IF query_type = 1 THEN
RETURN QUERY
SELECT "Westminster".*
FROM "Westminster"
WHERE ("Westminster".intersects = false AND "Westminster".area <= 100);
ELSE IF query_type = 0 THEN
RETURN QUERY
SELECT "Westminster".*
FROM "Westminster";
END IF;
END
$do$
However I get the following error, ERROR: cannot use RETURN QUERY in a non-SETOF function.
Does anyone know how I can get the above code to work? Thank you.
UPDATE: This ended up working for me:
CREATE OR REPLACE FUNCTION my_function(query_type integer)
RETURNS SETOF "Westminster" LANGUAGE plpgsql as $$
BEGIN
IF query_type = 1 THEN
RETURN QUERY
SELECT "Westminster".*
FROM "Westminster"
WHERE ("Westminster".intersects = false AND "Westminster".area <= 100);
ELSIF query_type = 0 THEN
RETURN QUERY
SELECT "Westminster".*
FROM "Westminster";
END IF;
END;
$$;
I then called the function like this:
SELECT * FROM my_function(1);
From the documentation:
The code block is treated as though it were the body of a function with no parameters, returning void.
You can use RETURN QUERY only in a function returning SETOF <type> or TABLE(...). Use the table "Westminster" as the resulting type, e.g.:
CREATE OR REPLACE FUNCTION my_function(query_type int)
RETURNS SETOF "Westminster" LANGUAGE plpgsql as $$
BEGIN
IF query_type = 1 THEN
RETURN QUERY
SELECT "Westminster".*
FROM "Westminster"
WHERE ("Westminster".intersects = false AND "Westminster".area <= 100);
ELSIF query_type = 0 THEN
RETURN QUERY
SELECT "Westminster".*
FROM "Westminster";
END IF;
END;
$$;
-- exemplary use:
SELECT * FROM my_function(1);
Note the proper use of ELSIF.
I don't think anonymous code blocks support it. Try creating a function and defining its resultset to table, e.g:
CREATE OR REPLACE FUNCTION myfunc() RETURNS TABLE (val INT) AS $$
BEGIN
RETURN QUERY SELECT 1;
END;
$$ LANGUAGE plpgsql;
To call your function you could use:
SELECT * FROM myfunc();
Note: keep in mind that the table declared on the function's header needs to have the same fields returned in the RETURN QUERY statement.

Check Results Count in Postgres Function Before Returning

I have a postgres function that I'd like to return the result of a query, but I'd like it to return nothing if that query matches more than 1 record.
So, something like:
CREATE OR REPLACE FUNCTION myFunc(_a text, _b text)
RETURNS yy
LANGUAGE plpgsql
STABLE
PARALLEL SAFE
AS $$
BEGIN
RETURN QUERY
SELECT *
FROM yy
WHERE a = x
AND b = y;
END;
$$;
Except, it should return nothing if that query matches more than 1 record.
CREATE OR REPLACE FUNCTION myFunc(_a text, _b text)
RETURNS SETOF yy -- To be able to return "nothing"
LANGUAGE plpgsql
STABLE
PARALLEL SAFE
AS $$
DECLARE
result yy;
BEGIN
SELECT *
INTO STRICT result -- STRICT allows to check that exactly one row returned
FROM yy
WHERE a = x
AND b = y;
RETURN NEXT result; -- RETURN NEXT - return yet another row for "RETURNS SETOF" function
EXCEPTION
WHEN no_data_found OR too_many_rows THEN -- When no data or more then one rows
RETURN; -- Nothing to return, just exit
END;
$$;
i guess this can help you out.
CREATE OR REPLACE FUNCTION database.myFunction(
IN text,IN text)
RETURNS TABLE(firstField, secondField, lastField) AS
$BODY$
--sql string is the variable containing the final sql code
declare sql_string text;
declare regs numeric;
begin
--this is what happens in case count<1
sql_string = 'select 0,0,0';
--now we count them
regs = (select count(firstField) from mytable where a=b)::numeric;
--if >=1, then whe get the whole data
if (regs>=1) then
sql_string = 'select firstField,secondField, lastField from mytable where a=b';
end if;
--and return to you...
return query EXECUTE sql_string;
end;