Is there any way how to express a variable in PostgreSQL as a string?
Example:
\set table_name countries
SELECT 'SELECT * FROM ' || CAST( :table_name, 'text' ) AS specificQuery;
leads to this error:
ERROR: syntax error at or near ","
LINE 1: SELECT 'SELECT * FROM ' || CAST( countries, 'text' ) AS specificQuery;
From the line sample above is obvious, that it doesn't convert "countries" to a string, but it is expressed as name of column/table.
How do I convert it?
Are you looking for something like this?:
SELECT * FROM :"table_name";
http://www.postgresql.org/docs/current/interactive/app-psql.html#APP-PSQL-VARIABLES
Something like this :
SELECT 'SELECT * FROM ' || countries::text AS specificQuery;
Related
I getting error like below: [42883] ERROR: operator does not exist: text || integer[] Hint: No operator matches the given name and argument type(s). You might need to add explicit type casts. I cannot fix this problem and tried so many times.
My Code:
DECLARE
arr_operators integer[1,2];
BEGIN
query1 := 'SELECT * FROM dist.' || _rec1.table_name || ' WHERE operator_id = ANY (''' || arr_operators || ''');';
FOR _rec IN EXECUTE query1 LOOP
END LOOP;
I think problem is happening when I am makin query string.But when I use this statement in query directly lik below is working well:
FOR _rec1 IN (SELECT * FROM dist.sirdarya WHERE id = any (arr_operators)) LOOP
INSERT INTO dist.justt(column1,column2) VALUES (_rec1.id,_rec1.msisdn);
END LOOP;
Any help is appreciated.
I suggest unnesting an array instead of concatenating string which could lead to SQL Injection:
SELECT *
FROM table_name
WHERE operator_id IN (SELECT * FROM unnest(arr_operators));
db<>fiddle demo
This part is particulary dangerous:
query1 := 'SELECT * FROM dist.' || _rec1.table_name
What if table name is let's say: ;DROP DATABASE ...;--?
It could be rewritten as:
query1 := FORMAT('SELECT * FROM dist.%I ...', _rec1.table_name);
I am trying to run the below query in a stored procedure and its not working.
We tried to print the query using NOTICE and we saw E gets appended to the regex and thats the reason the query doesnt show any output.
Not working
select order,version from mytable
where substring(version from quote_literal('[0-9]+\.[0-9]{1}'))
IN ('6.2') and order= 'ABC';
But the same query if i run from pgadmin query tool, it works fine.
Working
select order,version from mytable
where substring(version from '[0-9]+\.[0-9]{1}')
IN ('6.2') and order= 'ABC';
My requirement is to form the reqex dynamically in the stored procedure. Please guide on how to achieve this.
Below is the line of code in my stored procedure,
sql_query = sql_query || ' AND substring(version from ' || quote_literal( '[0-9]+\.[0-9]{1}' ) || ') IN (' || quote_literal(compatibleVersions) || ')';
raise notice 'Value: %', sql_query;
EXECUTE sql_query INTO query_result ;
and from notice i am getting the below output,
AND substring(version from E'[0-9]+\\.[0-9]{1}') IN ('{6.2}')
My requirement is to make this regex work.
I narrowed down to this query,
working
select substring(version from '[0-9]+\.[0-9]{1}') from mytable ;
not working
select substring(version from quote_literal('[0-9]+\.[0-9]{1}')) from mytable ;
Now i think its easy to fix it. You can try at your end also running this above queries.
Since your problem is not really the extended string literal syntax using E, but the string representation of the array in the IN list, your PL/pgSQL should look somewhat like this:
sql_query = sql_query ||
' AND substring(version from ' || quote_literal( '[0-9]+\.[0-9]{1}' ) ||
') IN (' || (SELECT string_agg(quote_literal(x), ', ')
FROM unnest(compatibleVersions
) AS x(x)) || ')';
quote_literal should be used in situations where u want to dynamically construct queries. In such situation quote_literal will be replaced by E in the final constructed query.
right way to use
select * from config_support_module where substring(firmware from '[0-9]+\.[0-9]{1}') IN ('6.2');
select * from config_support_module where substring(firmware from E'[0-9]+\.[0-9]{1}') IN ('6.2') ;
wrong usage of quote_literal in static queries
select * from config_support_module where substring(firmware from quote_literal('[0-9]+\.[0-9]{1}')) IN ('6.2') ;
This doesnt give you any errors/output.
quote_literal usage in dynamic queries
sql_query = sql_query || ' AND substring(version from ' || quote_literal( '[0-9]+\.[0-9]{1}' ) || ') ... .. ...
Is it possible to do something along the lines of:
define name1 = '23'
select * from my_db where value1 like '%' + name1 + %'
You are close. Here's a working example.
Use the variable command to register your variable. Then exec, which is a plsql block, to assign the value. Lastly use it in the select as a bind variable. As noted use || for concat operations not +
SQL> var name1 varchar2(20)
SQL> exec :name1 := '23';
PL/SQL procedure successfully completed.
SQL> select * from my_db where value1 like '%' || :name1 || '%';
Using the with statement allows you to inject the constant into the query.
WITH
name1 AS
(
SELECT 23 VALUE FROM DUAL
)
SELECT *
FROM MY_DB
WHERE VALUE1 LIKE '%' || (SELECT VALUE FROM NAME1) || '%'
;
What problem are you trying to solve by moving the constant out of the query?
How I pass a date parameter to dblink on postgres ?
SELECT * FROM dblink
(
'my connection'
,
'SELECT s.dtcreated FROM realvida.tbstudente s ' ||
' WHERE s.dtcreated' = $1 -- my parameter pass '02-01-2017'
) as result2( dtcreated date )
This way it returned me an error:
operator does not exist: date = integer
change 'SELECT s.dtcreated FROM realvida.tbstudente s ' ||
' WHERE s.dtcreated' = $1
to
format('SELECT s.dtcreated FROM realvida.tbstudente s WHERE s.dtcreated = %L',$1)
When I run the following command from a function I defined, I get the error "EXECUTE of SELECT ... INTO is not implemented". Does this mean the specific command is not allowed (i.e. "SELECT ...INTO")? Or does it just mean I'm doing something wrong? The actual code causing the error is below. I apologize if the answer is already out here, however I looked and could not find this specific error. Thanks in advance... For whatever it's worth I'm running 8.4.7
vCommand = 'select ' || stmt.column_name || ' as id ' ||
', count(*) as nCount
INTO tmpResults
from ' || stmt.table_name || '
WHERE ' || stmt.column_name || ' IN (select distinct primary_id from anyTable
WHERE primary_id = ' || stmt.column_name || ')
group by ' || stmt.column_name || ';';
EXECUTE vCommand;
INTO is ambiguous in this use case and then is prohibited there.
You can use a CREATE TABLE AS SELECT instead.
CREATE OR REPLACE FUNCTION public.f1(tablename character varying)
RETURNS integer
LANGUAGE plpgsql
AS $function$
begin
execute 'create temp table xx on commit drop as select * from '
|| quote_ident(tablename);
return (select count(*) from xx);
end;
$function$
postgres=# select f1('omega');
f1
────
2
(1 row)