dynamic query postgres - postgresql

I am new to postgres and running following dynamic query
EXECUTE 'Select * from products';
I get following response.
ERROR: syntax error at or near "'Select * from products'"
LINE 1: EXECUTE 'Select * from products';
I Know this would be something basic I m missing

There is the EXECUTE statement of plpgsql, which would do what you are trying to do - execute an SQL query string. You tagged dynamic, so this may be what you are looking for.
Only works inside plpgsql functions or DO statements (anonymous code blocks). The distinction between EXECUTE and SQL-EXECUTE made clear in the fine manual:
Note: The PL/pgSQL EXECUTE statement is not related to the EXECUTE SQL
statement supported by the PostgreSQL server. The server's EXECUTE
statement cannot be used directly within PL/pgSQL functions (and is
not needed).
If you want to return values from a dynamic SELECT query as your example indicates, you need to create a function. DO statements always return void. More about returning values from a function in the very fine manual.

From the fine manual:
Synopsis
EXECUTE name [ ( parameter [, ...] ) ]
Description
EXECUTE is used to execute a previously prepared statement.
So EXECUTE doesn't execute a string of SQL, it execute a prepared statement that is identified by a name and you need to prepare the statement separately using PREPARE:
=> prepare stmt as select * from products;
=> execute stmt;
-- "select * from products" output goes here...

Related

Execute prepare statement in a sql function

CREATE OR REPLACE FUNCTION my_function2()
RETURNS VOID
LANGUAGE plpgsql AS
$func$
BEGIN
PREPARE "my-statement7" (text, text) AS
INSERT INTO "table" (key, a_id)
VALUES ($1, $2);
EXECUTE format('EXECUTE "my-statement7" (%1, %2)', 'value1', 'value2');
END;
$func$;
SELECT my_function2();
However this will return error.
I have run successfully when I do execute prepare statement in the command line but when I do it in a function it will prompt error. Somebody said the execute statement will be ambiguous in execute statement or function, so it need put execute into execute format. However, it doesn't work too.
I want to execute the prepare statement for insert because I got a lot of data got to insert in same format, but the data may need to insert to different table (also data are different), so I cannot just do insert multi or COPY for it. I think the prepare statement is the solution for me, but it cannot work in a function. This will bother me if I want to do a lot of "execute prepare statement" in a function.
In PL/SQL, queries are already prepared and cached, so you don't have to.
As each expression and SQL command is first executed in the function, the PL/pgSQL interpreter parses and analyzes the command to create a prepared statement, using the SPI manager's SPI_prepare function. Subsequent visits to that expression or command reuse the prepared statement.
Here's how you'd write it if you tried. Note the use of _ instead of - in the name to avoid quoting issues; no need to format.
CREATE OR REPLACE FUNCTION my_function2()
RETURNS VOID
LANGUAGE plpgsql AS
$func$
BEGIN
PREPARE my_statement7 (text, text) AS
INSERT INTO example (key, a_id)
VALUES ($1, $2);
EXECUTE my_statement7( 'value1', 'value2');
END;
$func$;
However, the first time it will fail (for reasons I don't entirely understand): ERROR: function my_statement7(unknown, unknown) does not exist. The second time it is called it will also fail: ERROR: prepared statement "my_statement7" already exists.

Executing query inside variable in PostgreSQL function

I'm new to postgres, for a scenario i stored SQL statements inside a table with respective to table name. in the function i'm trying to filter the table name by passing them as a parameter to get the query from the table. But when i execute the query from the variable it gives out error
"SQL Error [42P01]: ERROR: relation "public.table_name" does not exist
Where: PL/pgSQL function ops_data_refresh(text) line 45 at EXECUTE"
execute format('select query from public.ops_dw_table_load where target_table=''%s'' and is_active =true',main_table)
into qry1;
if qry1 is not null then
raise notice '%',qry1;
execute qry1;
raise notice output insert into public.table_name select * from stage.table_name;
with raise notice im able to see the query which is in the table, if I run it manually things are working fine. but when running from function it throws the above error.
There is an SQL injection bug in your code. It should be:
EXECUTE format('SELECT ... target_table = %L ...', main_table);
But the problem is in the second EXECUTE: the query references a table that does not exist. Either change the query or create the table.

Loop through tables in postgresql trigger

I'm trying to build a trigger on a table, depending on other tables. So after search I have something like this
in the trigger :
begin
table_name=select (...) from information schema ;
execute format('some stuff
for i in select ... loop
insert into table (...) select (...) from %I
end loop',table)
But when firing the trigger I get this error:
SQL Error [42601]: ERROR: syntax error on or near « FOR »
I can't understand why-any ideas ?
With EXECUTE (dynamic SQL) you can only execute SQL statements. You are trying to execute a PL/pgSQL block.
You have three options:
The query string only contains the INSERT statement, and the loop is regular SQL.
The query string is a DO SQL statement that contains the whole block.
Rather than writing a FOR loop, write a dynamic statement like
INSERT INTO ...
SELECT ... FROM %I

How to execute string query

It is known that you can do EXECUTE SELECT * FROM table1. But how can I execute string queries assuming that the string is valid query for example: EXECUTE 'SELECT * FROM table1;'
EXECUTE is a PL/pgSQL command and cannot be used in plain SQL queries.
You'll have to write a PL/pgSQL function to use EXECUTE, but the simplest way to do what you seem to want to do is to use RETURN QUERY EXECUTE to return the query results from the function.
You can define the function with RETURNS SETOF RECORD to avoid having to specify the result columns at function definition time, but then you need to specify them when you call the function.

dynamic sql query in postgres

I was attempting to use Dynamic SQL to run some queries in postgres.
Example:
EXECUTE format('SELECT * from result_%s_table', quote_ident((select id from ids where condition = some_condition)))
I have to query a table, which is of the form result_%s_table wherein, I need to substitute the correct table name (an id) from an another table.
I get the error ERROR: prepared statement "format" does not exist
Link: string substitution with query result postgresql
EXECUTE ... USING only works in PL/PgSQL - ie within functions or DO blocks written in the PL/PgSQL language. It does not work in plain SQL; the EXECUTE in plain SQL is completely different, for executing prepared statements. You cannot use dynamic SQL directly in PostgreSQL's SQL dialect.
Compare:
PL/PgSQL's EXECUTE ... USING; to
SQL's EXECUTE
See the 2nd last par in my prior answer.
In addition to not running except in PL/PgSQL your SQL statement is wrong, it won't do what you expect. If (select id from ids where condition = some_condition) returns say 42, the statement would fail if id is an integer. If it's cast to text you'd get:
EXECUTE format('SELECT * from result_%s_table', quote_ident('42'));
EXECUTE format('SELECT * from result_%s_table', '"42"');
EXECUTE 'SELECT * from result_"42"_table';
That's invalid. You actually want result_42_table or "result_42_table". You'd have to write something more like:
EXECUTE format('SELECT * from %s', quote_ident('result_'||(select id from ids where condition = some_condition)||'_table'))
... if you must use quote_ident.
CREATE OR REPLACE FUNCTION public.exec(
text)
RETURNS SETOF RECORD
LANGUAGE 'plpgsql'
AS $BODY$
BEGIN
RETURN QUERY EXECUTE $1 ;
END
$BODY$;
usage:
select * from exec('select now()') as t(dt timestamptz)
Try using
RETURN QUERY EXECUTE '<SQL Command>'
This will return data into form of table. You have to use this into stored function of PostgreSQL.
I have already created on full demonstration on custom filter and custom sorting using dynamic query of PostgreSQL.
Please visit this url:
http://www.dbrnd.com/2015/05/postgresql-dynamic-sql/
These all look more complicated than the OP's question. A different formatting should do the trick.. but it could absolutely the case that I don't understand.
From how I read OP's question, I think others in a similar situation may benefit from how I got it.
I am using Postgre on Redshift, and I ran into this issue and found a solution.
I was trying to create a dynamic query, putting in my own date.
date = dt.date(2018, 10, 30)
query = ''' select * from table where date >= ''' + str(my_date) + ''' order by date '''
But, the query entirely ignores the condition when typing it this way.
However, if you use the percent sign (%), you can insert the date correctly.
One correct way to write the above statement is:
query = ''' select * from table where date >= ''' + ''' '%s' ''' % my_date + ''' order by date '''
So, maybe this is helpful, or maybe it is not. I hope it helps at least one person in my situation!
Best wishes.
EXECUTE will work only on pl/pqsql environment.
instead of EXECUTE try with SELECT
SELECT format('SELECT * from result_%s_table', quote_ident((select id from ids where condition = some_condition))
output would be the dynamic query.