postgres SQL function with variables - postgresql

Can anyone tell me why does not insert this function anything into the table?
CREATE OR REPLACE FUNCTION insert_one(_temp VARCHAR(1000))
RETURNS void AS $$
DECLARE
TEMP INT := NULL;
BEGIN
SELECT "temptable"."id" INTO TEMP FROM "temptable" WHERE "tmpstr" = _temp;
IF TEMP IS NULL THEN
INSERT INTO "temptable"("tmpstr") values(_temp);
SELECT CURRVAL("id") FROM "temptable" INTO TEMP;
END IF;
END;
$$ LANGUAGE plpgsql;

You probably get an error because there is no sequence called id.
You are probably looking for
INSERT INTO temptable (tmpstr)
VALUES (_temp)
ON CONFLICT DO NOTHING
RETURNING id;

Related

Argument not taking the value from Postgres function

I have a simple Postgres function where I want to take table_name as a parameter and pass it into an argument and delete the data from table by condition.
CREATE OR REPLACE FUNCTION cdc.audit_refresh(tablename text)
RETURNS integer AS
$$
BEGIN
delete from tablename where id<4;
RETURN(select 1);
END;
$$ LANGUAGE plpgsql;
select cdc.audit_refresh('cdc.adf_test');
But it throws out an error that tablename
ERROR: relation "tablename" does not exist in the delete statement.(refer snapshot)
What you want to achieve is to execute Dynamic SQL statements. You can do this with EXECUTE. See more here
CREATE OR REPLACE FUNCTION audit_refresh(tablename text)
RETURNS integer AS
$$
DECLARE
stmt TEXT;
BEGIN
stmt = 'delete from '||tablename||' where id<4;';
EXECUTE stmt;
RETURN 1;
END
$$ LANGUAGE plpgsql;

Query has no destination for result data when try to make search filter [duplicate]

I am trying to fetch data from remote db by using dblink through function but getting an error "query has no destination for result data". I am using plpgsql language to do the same.
Function:
CREATE OR REPLACE FUNCTION fun()
RETURNS text AS
$$
begin
select dblink_connect(
'port=5432 dbname=test user=postgres password=****');
WITH a AS (
SELECT *
FROM dblink(
'SELECT slno,fname,mname,lname
FROM remote_tbl'
) AS t (slno int, fname text, mname text, lname text)
)
, b AS (
INSERT INTO temptab1
SELECT slno, name
FROM a
)
, c AS (
INSERT INTO temptab2
SELECT slno, name
FROM a
)
INSERT INTO temptab3
SELECT slno, name
FROM a;
select dblink_disconnect();
end;
$$
LANGUAGE plpgsql;
Calling Function:
select fun();
Error: query has no destination for result data
The stored procedure won't just return the result of the last SELECT. You need to actually return the value:
CREATE OR REPLACE FUNCTION fun() RETURNS text AS $$
BEGIN
--- ....
RETURN(SELECT dblink_disconnect());
END
$$ LANGUAGE plpgsql;
You're getting the error because Postgres expects the function to return something of type text, but your function doesn't return anything.
Use a plain SQL function instead of PL/PgSQL, or use SELECT INTO and ordinary RETURN.
Reason for the error you're getting is because there is no return in between your BEGIN and END for example:
BEGIN
update mytable set lastcodeused = to_char(cast(lastcodeused as INTEGER)+1, 'FM999999999999999999') where
classid = classIdVar and appid= appIdInt
RETURNING concat(pageUniqueCode,lastcodeused) as pageUniqueCode
into taskcode;
return taskcode;
END;
If you have this error using a pgplsql procedure or function, and you are sure that the return is defined correctly, there exists a different non-intuitive cause. I needed some time to realize this so I think it is worth sharing. I had a function like this:
CREATE OR REPLACE FUNCTION "db".fn_x(
id integer)
RETURNS TABLE(b_val varchar(100), c_val varchar(100))
LANGUAGE 'plpgsql'
AS $BODY$
DECLARE
var_b_val varchar(100);
var_c_val varchar(100);
BEGIN
select var_b, var_c
-- Missing INTO clause was the cause of the error.
var_b_val, var_c_val
from "db".table_y where y_id = id;
return query(select var_b_val, var_c_val);
END;
$BODY$;
Just adding that missing INTO clause made the function work correctly.
In conclusion, this error can also trigger on silent syntax errors.

Postgres - Why is the temporary table created in one function undefined in another function?

this is a Postgres related question.
I can't figure out why I get ERROR undefined_table relation "temp_table" does not exist
I tried all sorts of things, but maybe I don't really understand how I correctly use a temporary table in a function that was created in another function.
CREATE FUNCTION api.test() RETURNS BOOLEAN LANGUAGE 'plpgsql' SECURITY DEFINER AS $$
BEGIN
CREATE TEMP TABLE temp_table( id INT NOT NULL) ON COMMIT DROP;
INSERT INTO temp_table (id) VALUES (1), (2);
RETURN TRUE;
END;
$$;
CREATE FUNCTION api.test_id(p_id INT) RETURNS BOOLEAN LANGUAGE 'plpgsql' SECURITY DEFINER AS $$
DECLARE
v_id INTEGER;
BEGIN
SELECT id INTO v_id FROM temp_table WHERE id = p_id LIMIT 1;
return v_id IS NOT NULL;
END;
$$;
PS: I create the temporary table in a function to protect it from being accessed outside of the functions by a different role.
I tested your code. It works if in the same transaction.
You are working from different transactions. See here:
https://www.postgresql.org/docs/current/sql-createtable.html#SQL-CREATETABLE-COMPATIBILITY
At "Temporary Tables"

inserting record from one table to another using record in postgres for loop

I'm trying to insert data from one table to another in postgres using for...loop. The approach is given below.
DO LANGUAGE PLPGSQL $$
DECLARE
data record;
BEGIN
FOR data IN SELECT * FROM forall_data
LOOP
INSERT INTO for_loop values data;<br>
END LOOP;
END;
$$
I've used record for the row iteration but couldn't find out how to insert that 'data' into 'for_loop' table. When I run this code it gives me the following error:
ERROR: syntax error at or near "data"
LINE 9: INSERT INTO for_loop values data;
^
Here are my two tables.
create table forall_data(
nid numeric(15,0)not null,
name varchar(15) not null,
city varchar(10) not null,
contact numeric(11,0) not null
);
create table for_loop(
nid numeric(15,0)not null,
name varchar(15) not null,
city varchar(10) not null,
contact numeric(11,0) not null
);
What should I try here to insert that 'data' record into 'for_loop' table? Thanks in advance.
'data' is untyped record, so I have to mention the column name to retrieve the value of this record.
DO LANGUAGE PLPGSQL $$
DECLARE
data record;
BEGIN
FOR data IN SELECT * FROM forall_data
LOOP
INSERT INTO for_loop values (data.nid,data.name,data.city,data.contact);
END LOOP;
END;
$$
But using %rowtype or table type is more flexible and no need to mention the column names to retrieve column value from the variable
DO LANGUAGE PLPGSQL $$
DECLARE
data forall_data; --- or data forall_data%rowtype
BEGIN
FOR data IN SELECT * FROM forall_data
LOOP
INSERT INTO for_loop select (data).*;
END LOOP;
END;
$$
cheers :)
use this code:
DO LANGUAGE PLPGSQL $$
DECLARE
rec record;
BEGIN
FOR rec IN SELECT * FROM budzet.forall_data
LOOP
INSERT INTO budzet.for_loop(nid, name , city , contact)
VALUES (rec.nid, rec.name , rec.city , rec.contact);
END LOOP;
END;
$$
You can try Loop with some exit condition.
DO LANGUAGE PLPGSQL $$
DECLARE
rec CURSOR FOR SELECT * FROM forall_data;
V_nid numeric;
V_name varchar(15);
V_city varchar(10);
V_contact numeric;
BEGIN
OPEN rec;
LOOP
FETCH rec INTO V_nid ,V_name ,V_city,V_contact;
EXIT WHEN(rec IS NULL);
INSERT INTO for_loop(nid, name , city , contact)
VALUES (V_nid , V_name , V_city , V_contact);
END LOOP;
CLOSE rec;
END;
$$
Hope it work for you.
EDIT: Alternately you can try this without using loop insert statement from one table and select statement from another table.
INSERT INTO for_loop(nid, name , city , contact)
select nid, name , city , contact FROM forall_data;

PostgreSQL: Query has no destination for result data

I am trying to fetch data from remote db by using dblink through function but getting an error "query has no destination for result data". I am using plpgsql language to do the same.
Function:
CREATE OR REPLACE FUNCTION fun()
RETURNS text AS
$$
begin
select dblink_connect(
'port=5432 dbname=test user=postgres password=****');
WITH a AS (
SELECT *
FROM dblink(
'SELECT slno,fname,mname,lname
FROM remote_tbl'
) AS t (slno int, fname text, mname text, lname text)
)
, b AS (
INSERT INTO temptab1
SELECT slno, name
FROM a
)
, c AS (
INSERT INTO temptab2
SELECT slno, name
FROM a
)
INSERT INTO temptab3
SELECT slno, name
FROM a;
select dblink_disconnect();
end;
$$
LANGUAGE plpgsql;
Calling Function:
select fun();
Error: query has no destination for result data
The stored procedure won't just return the result of the last SELECT. You need to actually return the value:
CREATE OR REPLACE FUNCTION fun() RETURNS text AS $$
BEGIN
--- ....
RETURN(SELECT dblink_disconnect());
END
$$ LANGUAGE plpgsql;
You're getting the error because Postgres expects the function to return something of type text, but your function doesn't return anything.
Use a plain SQL function instead of PL/PgSQL, or use SELECT INTO and ordinary RETURN.
Reason for the error you're getting is because there is no return in between your BEGIN and END for example:
BEGIN
update mytable set lastcodeused = to_char(cast(lastcodeused as INTEGER)+1, 'FM999999999999999999') where
classid = classIdVar and appid= appIdInt
RETURNING concat(pageUniqueCode,lastcodeused) as pageUniqueCode
into taskcode;
return taskcode;
END;
If you have this error using a pgplsql procedure or function, and you are sure that the return is defined correctly, there exists a different non-intuitive cause. I needed some time to realize this so I think it is worth sharing. I had a function like this:
CREATE OR REPLACE FUNCTION "db".fn_x(
id integer)
RETURNS TABLE(b_val varchar(100), c_val varchar(100))
LANGUAGE 'plpgsql'
AS $BODY$
DECLARE
var_b_val varchar(100);
var_c_val varchar(100);
BEGIN
select var_b, var_c
-- Missing INTO clause was the cause of the error.
var_b_val, var_c_val
from "db".table_y where y_id = id;
return query(select var_b_val, var_c_val);
END;
$BODY$;
Just adding that missing INTO clause made the function work correctly.
In conclusion, this error can also trigger on silent syntax errors.