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