I’m trying to create a function which references a temporary table in PostgreSQL 8.4. Based on my research it seems the best way to do this is to use the EXECUTE
command to execute my query from a defined string.
Unfortunately I’m getting an odd syntax error when trying to create the function.
My current function definition is as follows:
CREATE OR REPLACE FUNCTION example() RETURNS void AS $$
EXECUTE 'INSERT INTO table1 (col1, col2, col3) SELECT col1, col2, col3 from temp_table';
$$ LANGUAGE SQL;
The error I am getting is:
ERROR: syntax error at or near "'INSERT INTO table1 (col1, col2, col3) SELECT col1, col2, col3 from temp_table'"
LINE 2: execute 'INSERT INTO table1 (col1, col2, col3) SELECT col1...
It seems I get the same error regardless of what is actually in the string literal.
My questions are, 1) what is the correct syntax for using the EXECUTE feature, and 2) is there a better way to write a function like this that references a temporary table?
asked Jul 28, 2011 at 15:15
I think your problem is the language you’re using. EXECUTE in the SQL language:
EXECUTE
is used to execute a previously prepared statement. Since prepared statements only exist for the duration of a session, the prepared statement must have been created by aPREPARE
statement executed earlier in the current session.
isn’t the same as EXECUTE in PL/pgSQL:
Oftentimes you will want to generate dynamic commands inside your PL/pgSQL functions, that is, commands that will involve different tables or different data types each time they are executed. PL/pgSQL’s normal attempts to cache plans for commands (as discussed in Section 39.10.2) will not work in such scenarios. To handle this sort of problem, the
EXECUTE
statement is provided:EXECUTE command-string [ INTO [STRICT] target ] [ USING expression [, ... ] ];
You’re using the SQL EXECUTE (which executes a prepared statement) when you want to be using the PL/pgSQL EXECUTE (which executes a string as SQL).
Try this:
CREATE OR REPLACE FUNCTION example() RETURNS void AS $$
BEGIN
EXECUTE 'INSERT INTO table1 (col1, col2, col3) SELECT col1, col2, col3 from temp_table';
END;
$$ LANGUAGE PLPGSQL;
Or, another example that seems closer to what you seem to be trying to do:
create or replace function example(tname text) returns void as $$
begin
execute 'insert into ' || tname || ' (name) values(''pancakes'')';
end;
$$ language plpgsql;
That will insert 'pancakes'
into the table that you pass in the tname
argument to the function.
answered Jul 28, 2011 at 17:15
mu is too shortmu is too short
427k70 gold badges834 silver badges801 bronze badges
EXECUTE
is used to execute prepared statements and only expects a prepared statement name as argument.
If you are trying to execute an SQL statement (as in your example) simply include it in the body of the function.
Check the manual for more info about «Query Language (SQL) Functions».
OTOH if you are trying to create a PL/pgSQL function (which is not what you’ve shown in your question), then you need to convert your function to be a PL/pgSQL function.
answered Jul 28, 2011 at 15:20
Milen A. RadevMilen A. Radev
60.4k22 gold badges106 silver badges110 bronze badges
1
It is a example tested by me where I use EXECUTE to run a select and put its result in a cursor.
1. Create the table:
create table people (
nickname varchar(9),
name varchar(12),
second_name varchar(12),
country varchar(30)
);
2. Create the function:
CREATE OR REPLACE FUNCTION fun_find_people (col_name text, col_value varchar)
RETURNS void AS
$BODY$
DECLARE
local_cursor_p refcursor;
row_from_people RECORD;
BEGIN
open local_cursor_p FOR
EXECUTE 'select * from people where '|| col_name || ' LIKE ''' || col_value || '%'' ';
raise notice 'col_name: %',col_name;
raise notice 'col_value: %',col_value;
LOOP
FETCH local_cursor_p INTO row_from_people; EXIT WHEN NOT FOUND;
raise notice 'row_from_people.nickname: %', row_from_people.nickname ;
raise notice 'row_from_people.name: %', row_from_people.name ;
raise notice 'row_from_people.country: %', row_from_people.country;
END LOOP;
END;
$BODY$ LANGUAGE 'plpgsql'
3. Run the function
select fun_find_people('name', 'Cristian');
select fun_find_people('country', 'Chile');
answered Feb 18, 2017 at 22:54
CristianCristian
5486 silver badges8 bronze badges
Alternatively, you can run it inside an anonymous code-block using DO
.
According to the documentation (emphasis mine):
DO
executes an anonymous code block, or in other words a transient anonymous function in a procedural language.The code block is treated as though it were the body of a function with no parameters, returning void. It is parsed and executed a single time.
This allows you to run constructed SQL that you would normally not be able to run, without forcing you to build a function to call it:
DO $$
BEGIN
execute 'ALTER DATABASE ' || current_database() || ' SET timezone TO ''UTC''';
execute 'SET timezone TO ''UTC''';
END;
$$
instead of:
CREATE OR REPLACE FUNCTION fix_database_timezone()
RETURNS void AS
$BODY$
BEGIN
execute 'ALTER DATABASE ' || current_database() || ' SET timezone TO ''UTC''';
execute 'SET timezone TO ''UTC''';
END;
$BODY$ LANGUAGE 'plpgsql';
fix_database_timezone();
answered Aug 16, 2019 at 17:27
ANevesANeves
6,2193 gold badges39 silver badges63 bronze badges
Answers of > EXECUTE syntax error in postgresql
I think your problem is the language you’re w3coded syntax near using. EXECUTE in the SQL language:,EXECUTE is w3coded syntax near used to execute prepared statements and only w3coded syntax near expects a prepared statement name as w3coded syntax near argument.,You’re using the SQL EXECUTE (which w3coded syntax near executes a prepared statement) when you want to w3coded syntax near be using the PL/pgSQL EXECUTE (which executes a w3coded syntax near string as SQL).,If you are trying to execute an w3coded syntax near SQL statement (as in your example) simply w3coded syntax near include it in the body of the function.
Oftentimes you will want to generate dynamic commands inside your PL/pgSQL functions, that is, commands that will involve different tables or different data types each time they are executed. PL/pgSQL’s normal attempts to cache plans for commands (as discussed in Section 39.10.2) will not work in such scenarios. To handle this sort of problem, the EXECUTE
statement is provided:
EXECUTE command-string [ INTO [STRICT] target ] [ USING expression [, ... ] ];
Oftentimes you will want to generate dynamic commands inside your PL/pgSQL functions, that is, commands that will involve different tables or different data types each time they are executed. PL/pgSQL’s normal attempts to cache plans for commands (as discussed in Section 39.10.2) will not work in such scenarios. To handle this sort of problem, the EXECUTE
statement is provided:
EXECUTE command-string [ INTO [STRICT] target ] [ USING expression [, ... ] ];
Try this:
CREATE OR REPLACE FUNCTION example() RETURNS void AS $$
BEGIN
EXECUTE 'INSERT INTO table1 (col1, col2, col3) SELECT col1, col2, col3 from temp_table';
END;
$$ LANGUAGE PLPGSQL;
Or, another example that seems closer to what you seem to be trying to do:
create or replace function example(tname text) returns void as $$
begin
execute 'insert into ' || tname || ' (name) values(''pancakes'')';
end;
$$ language plpgsql;
1. Create the table:
create table people (
nickname varchar(9),
name varchar(12),
second_name varchar(12),
country varchar(30)
);
2. Create the function:
CREATE OR REPLACE FUNCTION fun_find_people (col_name text, col_value varchar)
RETURNS void AS
$BODY$
DECLARE
local_cursor_p refcursor;
row_from_people RECORD;
BEGIN
open local_cursor_p FOR
EXECUTE 'select * from people where '|| col_name || ' LIKE ''' || col_value || '%'' ';
raise notice 'col_name: %',col_name;
raise notice 'col_value: %',col_value;
LOOP
FETCH local_cursor_p INTO row_from_people; EXIT WHEN NOT FOUND;
raise notice 'row_from_people.nickname: %', row_from_people.nickname ;
raise notice 'row_from_people.name: %', row_from_people.name ;
raise notice 'row_from_people.country: %', row_from_people.country;
END LOOP;
END;
$BODY$ LANGUAGE 'plpgsql'
This allows you to run constructed SQL that you would normally not be able to run, without forcing you to build a function to call it:
DO $$
BEGIN
execute 'ALTER DATABASE ' || current_database() || ' SET timezone TO ''UTC''';
execute 'SET timezone TO ''UTC''';
END;
$$
instead of:
CREATE OR REPLACE FUNCTION fix_database_timezone()
RETURNS void AS
$BODY$
BEGIN
execute 'ALTER DATABASE ' || current_database() || ' SET timezone TO ''UTC''';
execute 'SET timezone TO ''UTC''';
END;
$BODY$ LANGUAGE 'plpgsql';
fix_database_timezone();
Current topics : EXECUTE syntax error in postgresql
Newly Added Questions
I am using an after update trigger in order recognize and log any changes made to records in the ‘tasks’ table. The column, and new and old value are all dynamic, so different every time.
This is what the trigger function looks like right now:
CREATE OR REPLACE FUNCTION fn_tasks_after_update()
RETURNS trigger
AS $BODY$
DECLARE
ri RECORD;
col_name TEXT;
BEGIN
FOR ri IN
SELECT column_name FROM information_schema.columns WHERE table_name = 'tasks'
LOOP
EXECUTE
'IF $1.' || ri.column_name || ' <> $2.' || ri.column_name || ' THEN
INSERT INTO tasks_log (task_id, type, "column", old_value, new_value)
VALUES ($1.id, $$update$$, $3, $1.' || ri.column_name || ', $2.' || ri.column_name || ');
END IF;'
USING NEW, OLD, ri.column_name;
END LOOP;
RETURN NEW;
END; $BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION fn_tasks_after_update()
OWNER TO postgres;
The trigger worked before adding the IF, and the syntax does not seem any different from what is in the ‘INSERT INTO tasks_log’ block.
This does work:
EXECUTE
'INSERT INTO tasks_log (task_id, type, "column", old_value, new_value)
VALUES ($1.id, $$update$$, $3, $1.' || ri.column_name || ', $2.' || ri.column_name || ');'
This does not work:
EXECUTE
'IF $1.' || ri.column_name || ' <> $2.' || ri.column_name || ' THEN
INSERT INTO tasks_log (task_id, type, "column", old_value, new_value)
VALUES ($1.id, $$update$$, $3, $1.' || ri.column_name || ', $2.' || ri.column_name || ');
END IF;'
What is going wrong?
Всем привет хочу создать таблицу в postgresql через python но возникает ошибка( cur.execute(«»»CREATE TABLE {}
psycopg2.errors.SyntaxError: ОШИБКА: ошибка синтаксиса (примерное положение: «688093622»)) вот код:
if user_id_v not in mas_user_id:
mas_user_id.append(user_id_v)
print('Новый пользователь БОТА: ', mas_user_id[-1])
conn = psycopg2.connect(
host='localhost',
database='',
user='',
password='',
port=5432
)
cur = conn.cursor()
# Создание таблицы
# Создание таблицы
cur.execute(f'''CREATE TABLE {user_id}
(ADMISSION INT PRIMARY KEY NOT NULL,
NAME TEXT NOT NULL,
AGE INT NOT NULL,
COURSE CHAR(50),
DEPARTMENT CHAR(50));''')
print("Table created successfully")
conn.commit()
conn.close()
conn.commit()
conn.close()
To execute a command with no result, the function change can be modified as follows:
Solution 1:
Instead of multiple statements, it can be rewritten as a single statement.
Implementing partial uniqueness is indicated by using it in the trigger.
Solution 2:
When attempting to add a trigger function from pgadmin UI, make sure to specify the function from BEGIN to END in the code tab. Postgres implicitly specifies «CREATE OR REPLACE FUNCTION» in the code.
EXECUTE syntax error in postgresql
Solution:
Executing a Command That Does Not Yield a Result
At times, it can be beneficial to assess an expression or SELECT query without retaining the outcome. This can be particularly useful when invoking a function that yields side-effects but lacks a meaningful result value. In PL/pgSQL, the PERFORM statement is utilized for this purpose.
emphasis mine.
Modify the function change from
select
to
perform
.
PostgreSQL Syntax error at or near FUNCTION on create, The EXECUTE FUNCTION syntax for CREATE TRIGGER statements was introduced in Postgres 11. In Postgres 10, you need to say EXECUTE PROCEDURE instead. This syntax was deprecated in Postgres 11 with the introduction of procedures, which are distinct from functions and cannot be used …
Syntax error while using EXECUTE format in Postgresql Function to assign variable
Solution 1:
I wish to execute the second statement exclusively when cnt is equal to zero.
The text can be restated as one sentence.
UPDATE table1
SET field1 = ...
WHERE id = ...
AND NOT EXISTS (SELECT *
FROM table1
WHERE field2 = ...
AND field1 != ...
AND id != ...);
If the intention is to achieve partial uniqueness, utilizing it in a trigger suggests an attempt at implementation. In such cases, considering the use of a partial/filtered index is also a viable alternative.
CREATE UNIQUE INDEX uq ON table1(id, field1) WHERE field2 = ....;
Solution 2:
Even though @Lukasz’s solution could be effective, I ultimately opted for the implementation recommended by @stickybit in the question’s comments.
Answer:
CREATE OR REPLACE FUNCTION my_function() RETURNS TRIGGER AS $$
DECLARE
cnt bigint;
BEGIN
IF NEW.field1 = 'DECLINED' THEN
cnt := ('SELECT count(*) FROM table1 WHERE field2 = NEW.field2 AND field1 != NEW.field1 AND id != NEW.id;')
IF cnt = 0 THEN
'UPDATE table1 SET field1 = 'DECLINED' WHERE id = NEW.field2';
END IF;
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
Syntax error when declaring a postgres variable, 1 Answer. You cannot declare a variable in pure SQL in Postgres, unlike other RDBMS such as SQL Server or MySQL. Your code compiles properly in this Postgres 12 db fiddle when I put it within plgpsql procedure (still, you should consider another name that number for a variable). create procedure test_proc () …
PostgreSQL Syntax error at or near FUNCTION on create trigger
Solution 1:
Postgres 11 introduced the
EXECUTE FUNCTION
syntax for
CREATE TRIGGER
statements.
Instead of saying
EXECUTE PROCEDURE
in Postgres 10, you need to use it.
With the implementation of procedures in Postgres 11, the previously deprecated syntax can no longer be used to implement a trigger. Procedures are separate from functions and serve a distinct purpose.
Solution 2:
When attempting to add a trigger function from the pgAdmin UI, you must specify the function in the code tab using the BEGIN and END keywords. This is because PostgreSQL implicitly defines the code as «CREATE OR REPLACE FUNCTION ****() RETURNS TRIGGER AS $$».
When I try to create a function in PostgreSQL, I get, A simple language sql function would be more efficient if you don’t have any procedural code (if, while, or similar constructs) in your function – a_horse_with_no_name Feb 27, 2019 at 6:56
PostgreSQL — ERROR: syntax error at or near «;» END; In an IF-ELSE IF code
Solution:
To resolve the issue, the solution entails substituting the «ELSE IF» statement with «ELSIF»…
Additionally, I made modifications such as converting the strings ‘years’ into integers (‘1874’ -> 1874) and replacing startyear with the new variable NEW.startyear.
CREATE OR REPLACE FUNCTION title_basics_partitioner()
RETURNS TRIGGER AS $$
BEGIN
IF (NEW.startyear is null) THEN
INSERT INTO startyear_null VALUES (NEW.*);
ELSIF (NEW.startyear >= 1874 AND NEW.startyear < 1894) THEN
INSERT INTO startyear_1874_1894 VALUES (NEW.*);
ELSIF (NEW.startyear >= 1894 AND NEW.startyear < 1914) THEN
INSERT INTO startyear_1894_1914 VALUES (NEW.*);
ELSIF (NEW.startyear >= 1914 AND NEW.startyear < 1934) THEN
INSERT INTO startyear_1914_1934 VALUES (NEW.*);
ELSIF (NEW.startyear >= 1934 AND NEW.startyear < 1954) THEN
INSERT INTO startyear_1934_1954 VALUES (NEW.*);
ELSIF (NEW.startyear >= 1954 AND NEW.startyear < 1974) THEN
INSERT INTO startyear_1954_1974 VALUES (NEW.*);
ELSIF (NEW.startyear >= 1974 AND NEW.startyear < 1994) THEN
INSERT INTO startyear_1974_1994 VALUES (NEW.*);
ELSIF (NEW.startyear >= 1994 AND NEW.startyear < 2014) THEN
INSERT INTO startyear_1994_2014 VALUES (NEW.*);
ELSIF (NEW.startyear >= 2014 AND NEW.startyear < 2115) THEN
INSERT INTO startyear_2014_2115 VALUES (NEW.*);
ELSE
RAISE EXCEPTION 'Out of range year value. Fix the title_basics_insert_trigger() function!';
END IF;
RETURN NULL;
END;
$$
LANGUAGE plpgsql;
Sql — EXECUTE statement syntax error in PostgreSQL, But this results in a syntax error, just after the EXECUTE command. Am I not using it correctly? By the way, I am aware of the dangers of SQL injection and using EXECUTE willy-nilly. The queries that I am making are not designed for front-end use, and I am following the design patterns already set forth by the …