CREATE OR REPLACE FUNCTION test(name VARCHAR (255))
RETURNS INTEGER AS
$BODY$
DECLARE
emp_id INTEGER;
BEGIN
SELECT employee.employee_id into emp_id from employee where first_name = name;
DELETE FROM employee WHERE employee_id = emp_id;
return emp_id;
END
$BODY$
LANGUAGE plpgsql;
when i call the function its deleting all the records in my employee table.
First store value in a variable for given input and these execute delete command with this variable and return this variable.
-- PostgreSQL
-- create table and store data
create table employee (emp_id int, name varchar(255));
insert into employee values (1, 'Rahul'), (2, 'Biswas'), (3, 'Shuva');
-- create function
CREATE OR REPLACE FUNCTION test(p_name varchar(255))
RETURNS INTEGER AS
$BODY$
DECLARE v_emp_id INTEGER;
BEGIN
SELECT e.emp_id into v_emp_id from employee e where e.name = p_name;
DELETE FROM employee WHERE emp_id = v_emp_id;
return v_emp_id;
END
$BODY$
LANGUAGE plpgsql;
-- execute function
select * from test('Rahul');
Please check this url https://dbfiddle.uk/?rdbms=postgres_11&fiddle=4c134787dafd8fe58b032d700168318d
I'm writing postgresql function which inserts data and returns successfully inserted data rows.
The code is below.
CREATE OR REPLACE FUNCTION public.fn_insert_test(json_data jsonb)
returns table(col_1 varchar(255),
col_2 varchar(255),
col_3 timestamp)
LANGUAGE plpgsql
AS $function$
declare
--
begin
with my_table as (
with my_table1(my_json) as (
values(
json_data
)
)
insert into "test"(col_1, col_2, col_3)
select
elem->>'val1', elem->>'val2', now()
from
my_table1 t, jsonb_array_elements(my_json->'_data') elem
on conflict(col_1) do nothing
returning *
)
select * from my_table;
end
$function$
;
select fn_insert_test('{"_data": [{"val1":"1", "val2":"1"}, {"val1":"2", "val2":"2"}]}');
It occurs error below.
SQL Error [42702]: ERROR: column reference "col_1" is ambiguous
Detail: It could refer to either a PL/pgSQL variable or a table column.
Where: PL/pgSQL function fn_insert_test(jsonb) line 5 at SQL statement
[edit]
This is not the real problem here. There is a lot of problems in your code :
-> If you want to return a table, you have to use 'return query' : http://www.postgresqltutorial.com/plpgsql-function-returns-a-table/
-> I do not think you can use the WITH like you do: https://www.postgresql.org/docs/current/queries-with.html
Here is a functoinnal version of your code. But I am not quite sure of what you want :
CREATE OR REPLACE FUNCTION public.fn_insert_test(json_data jsonb)
returns table(col_1 varchar(255),
col_2 varchar(255),
col_3 timestamp)
LANGUAGE plpgsql AS
$$
declare
--json_data jsonb := '{"_data": [{"val1":"1", "val2":"1"}, {"val1":"2", "val2":"2"}]}';
begin
create temp table res (col_1 varchar (255), col_2 varchar (255), col_3 timestamp) on commit drop;
with my_table1(my_json) as
(
values(
json_data
)
)
, inserted as
(
insert into test(col_1, col_2, col_3)
select
elem->>'val1', elem->>'val2', now()
from
my_table1 t
, jsonb_array_elements(json_data->'_data') elem
on conflict do nothing
returning *
)
insert into res
select *
from inserted;
--raise notice '%', res_v;
return query select * from res;
end
$$
;
select fn_insert_test('{"_data": [{"val1":"1", "val2":"1"}, {"val1":"2", "val2":"2"}]}');
create or replace function demowhile_()
returns table (id integer,name varchar(50))
language 'plpgsql'
as $$
declare id integer;
declare name varchar(50);
begin
CREATE temporary TABLE demo_(id integer,name varchar(50));
CREATE temporary TABLE temp_ (id integer);
insert into temp_ (select id from demo);
while (select count(*) from temp_) <> 0
loop
id = (select top(1) id from temp_);
name = (select name from demo where id = id);
insert into demo_ values (id,name);
delete from temp_ where id = id;
end loop;
return query select id,name from demo;
end;
$$;
****while executing it is giving error like ****
select * from demowhile();
**ERROR: column reference "id" is ambiguous
LINE 1: insert into temp_ (select id,name from demo)
^
DETAIL: It could refer to either a PL/pgSQL variable or a table column.
QUERY: insert into temp_ (select id,name from demo)
CONTEXT: PL/pgSQL function demowhile() line 9 at SQL statement
SQL state: 42702**
demowhile_() returns table (id integer,name varchar(50) is basically the same thing as demowhile_(out id integer, out name varchar(50)) returns setof record
The id output column can be referenced directly from within the function. You've then also created a function variable named id. So when you assign a value to id, are you assigning to the output parameter or the declared variable? PG doesn't know, so you get that error.
And of course the simple solution is to give each a unique name.
I have a problem with recursion in a trigger.
I have the table:
CREATE TABLE employees(
task int4 NOT NULL,
first_name varchar(40) NOT NULL,
last_name varchar(40) NOT NULL,
PRIMARY KEY (task, cli_id_number)
);
When I insert the values:
(123, name, last)
i want to automatically insert these values as well:
(321, name, last)
I do this in the following way, but apparently the trigger is recursive and after the first recursion it tries to insert the previously inserted value.
CREATE OR REPLACE FUNCTION insert_task() RETURNS trigger AS $BODY$
BEGIN
IF new.task = '123' AND (
SELECT cant FROM (
SELECT name, task, count(*) AS cant
FROM client_task
WHERE name = NEW.name AND task = NEW.task
GOUP BY 1,2
HAVING count(*) <= 1
) t) = 1 THEN
INSERT INTO client_task(task, name, last_name)
VALUES('321', NEW.task, NEW.name, NEW.last_name);
RETURN NEW;
ELSE
IF NEW.task = '321' AND (
SELECT cant FROM (
SELECT name, task, count(*) AS cant
FROM client_task
WHERE name = NEW.name AND task = NEW.task
GROUP BY 1, 2
HAVING count(*) <=1
) t) = 1 THEN
INSERT INTO client_task(task, name, last_name)
VALUES('123', NEW.task, NEW.name, NEW.last_name);
RETURN NEW;
END IF;
END IF;
RETURN NULL;
END; $BODY$ LANGUAGE 'plpgsql';
Any help appreciated.
Use the function pg_trigger_depth(). According to the documentation it returns:
current nesting level of PostgreSQL triggers (0 if not called,
directly or indirectly, from inside a trigger)
CREATE TRIGGER insert_task
AFTER INSERT ON employees
FOR EACH ROW
WHEN (pg_trigger_depth() = 0)
EXECUTE PROCEDURE insert_task()
I have a table with two columns.
Example:
create table t1
(
cola varchar,
colb varchar
);
Now I want to insert the rows from function.
In the function: I want to use two parameters which is of type varchar to insert the values into the above table. I am passing the string to insert into the table.
I am passing two string of characters as a parameters to the function:
Parameters:
cola varchar = 'a,b,c,d';
colb varchar = 'e,f,g,h';
The above parameters have to insert into the table like this:
cola colb
----------------
a e
b f
c g
d h
My try:
create or replace function fun_t1(cola varchar,colb varchar)
returns void as
$body$
Declare
v_Count integer;
v_i integer = 0;
v_f1 text;
v_cola varchar;
v_colb varchar;
v_query varchar;
Begin
drop table if exists temp_table;
create temp table temp_table
(
cola varchar,
colb varchar
);
v_Count := length(cola) - length(replace(cola, ',', ''));
raise info '%',v_Count;
WHILE(v_i<=v_Count) LOOP
INSERT INTO temp_table
SELECT LEFT(cola,CHARINDEX(',',cola||',',0)-1)
,LEFT(colb,CHARINDEX(',',colb||',',0)-1);
cola := overlay(cola placing '' from 1 for CHARINDEX(',',cola,0));
colb := overlay(colb placing '' from 1 for CHARINDEX(',',colb,0));
v_i := v_i + 1;
END LOOP;
for v_f1 IN select * from temp_table loop
v_cola := v_f1.cola; /* Error occurred here */
v_colb := v_f1.colb;
v_query := 'INSERT INTO t1 values('''||v_cola||''','''||v_colb||''')';
execute v_query;
end loop;
end;
$body$
language plpgsql;
Note: In the function I have used temp_table that is according to the requirement which
I am using for the other use also in the function which I have not display here.
Calling function:
SELECT fun_t1('a,b,c','d,e,f');
Getting an error:
missing FROM-clause entry for table "v_f1"
Try this way using split_part() : -
create or replace function ins_t1(vala varchar,valb varchar,row_cnt int) returns void as
$$
BEGIN
FOR i IN 1..row_cnt LOOP -- row_cnt is the number rows you need to insert (ex. 4 or 5 or whatever it is)
insert into t1 (cola,colb)
values (
(select split_part(vala,',',i))
,(select split_part(valb,',',i))
);
END LOOP;
END;
$$
language plpgsql
function call :select ins_t1('a,b,c,d','e,f,g,h',4)
As mike-sherrill-cat-recall said in his answer by using regexp_split_to_table
create or replace function fn_t1(vala varchar,valb varchar) returns void
as
$$
insert into t1 (cola, colb)
select col1, col2 from (select
trim(regexp_split_to_table(vala, ',')) col1,
trim(regexp_split_to_table(valb, ',')) col2)t;
$$
language sql
function call :select fn_t1('a,b,c,d','e,f,g,h')
If there's no compelling reason to use a function for this, you can just split the text using a regular expression. Here I've expressed your arguments as a common table expression, but that's just for convenience.
with data (col1, col2) as (
select 'a, b, c, d'::text, 'e, f, g, h'::text
)
select
trim(regexp_split_to_table(col1, ',')) as col_a,
trim(regexp_split_to_table(col2, ',')) as col_b
from data;
col_a col_b
--
a e
b f
c g
d h
If there is a compelling reason to use a function, just wrap a function definition around that SELECT statement.
create function strings_to_table(varchar, varchar)
returns table (col_a varchar, col_b varchar)
as
'select trim(regexp_split_to_table($1, '','')),
trim(regexp_split_to_table($2, '',''));'
language sql
stable
returns null on null input;
select * from strings_to_table('a,b,c,d', 'e,f, g, h');
col_a col_b
--
a e
b f
c g
d h
My personal preference is usually to build functions like this to return tables rather than inserting into tables. To insert, I'd usually write a SQL statement like this.
insert into foo (col_a, col_b)
select col_a, col_b from strings_to_table('a,b,c,d', 'e,f,g,h');
The simpest way is using plpython for this.
create or replace function fill_t1(cola varchar, colb varchar) returns void as $$
for r in zip(cola.split(','), colb.split(',')):
plpy.execute(plpy.prepare('insert into t1(cola, colb) values ($1, $2)', ['varchar', 'varchar']), [r[0], r[1]])
$$ language plpythonu;
The result:
# create table t1 (cola varchar, colb varchar);
CREATE TABLE
# select fill_t1('1,2,3', '4,5,6');
fill_t1
---------
(1 row)
# select * from t1;
cola | colb
------+------
1 | 4
2 | 5
3 | 6
(3 rows)
You can read about Python zip function here: https://docs.python.org/2/library/functions.html#zip