Postgresql execute ошибка синтаксиса

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

Mike Deck's user avatar

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 a PREPARE 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 short's user avatar

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. Radev's user avatar

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

Cristian's user avatar

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();

Community's user avatar

answered Aug 16, 2019 at 17:27

ANeves's user avatar

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 …

Понравилась статья? Поделить с друзьями:
  • Postgresql ошибка отношение уже существует
  • Postgresql declare ошибка синтаксиса
  • Postgresql ошибка ошибочный литерал массива
  • Postgresql 42p01 ошибка отношение не существует
  • Postgresql ошибка нехватка памяти