web-dev-qa-db-fra.com

requête SQL dynamique dans PostgreSQL

J'essayais d'utiliser Dynamic SQL pour exécuter certaines requêtes dans postgres.

Exemple:

EXECUTE format('SELECT * from result_%s_table', quote_ident((select id from ids where condition = some_condition)))

Je dois interroger une table, qui est de la forme result_% s_table dans laquelle, je dois remplacer le nom de table correct (un id) d'une autre table.

J'obtiens l'erreur ERROR: prepared statement "format" does not exist

Lien: substitution de chaîne avec le résultat de la requête postgresql

19
psteelk

EXECUTE ... USING ne fonctionne que dans PL/PgSQL - c'est-à-dire dans les fonctions ou DO blocs écrit en langage PL/PgSQL. Cela ne fonctionne pas en SQL simple; le EXECUTE en clair SQL est complètement différent, pour l'exécution des instructions préparées. Vous ne pouvez pas utiliser SQL dynamique directement dans le dialecte SQL de PostgreSQL.

Comparer:

Voir l'avant-dernier pair dans ma réponse précédente .


En plus de ne pas fonctionner sauf en PL/PgSQL, votre instruction SQL est erronée, elle ne fera pas ce que vous attendez. Si (select id from ids where condition = some_condition) renvoie dire 42, l'instruction échouerait si id est un entier. S'il est converti en texte, vous obtiendrez:

EXECUTE format('SELECT * from result_%s_table', quote_ident('42'));
EXECUTE format('SELECT * from result_%s_table', '"42"');
EXECUTE 'SELECT * from result_"42"_table';

C'est invalide. Vous voulez réellement result_42_table ou "result_42_table". Il faudrait écrire quelque chose de plus comme:

EXECUTE format('SELECT * from %s', quote_ident('result_'||(select id from ids where condition = some_condition)||'_table'))

... si vous devez utiliser quote_ident.

28
Craig Ringer
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)
8
Inshua

Essayez d'utiliser

RETURN QUERY EXECUTE '<SQL Command>'

Cela renverra les données sous forme de tableau. Vous devez l'utiliser dans la fonction stockée de PostgreSQL.

J'ai déjà créé une démonstration complète sur le filtre personnalisé et le tri personnalisé en utilisant la requête dynamique de PostgreSQL. Veuillez visiter cette URL: http://www.dbrnd.com/2015/05/postgresql-dynamic-sql/

4
Anvesh

EXECUTE ne fonctionnera que sur l'environnement pl/pqsql.

au lieu de EXECUTE, essayez avec SELECT

 SELECT format('SELECT * from result_%s_table', quote_ident((select id from ids where condition = some_condition))

la sortie serait la requête dynamique.

1
solaimuruganv

Tout cela semble plus compliqué que la question du PO. Un formatage différent devrait faire l'affaire ... mais cela pourrait absolument être le cas que je ne comprends pas.

D'après la façon dont j'ai lu la question de OP, je pense que d'autres personnes dans une situation similaire peuvent bénéficier de la façon dont je l'ai obtenue.

J'utilise Postgre sur Redshift et j'ai rencontré ce problème et trouvé une solution.

J'essayais de créer une requête dynamique, en mettant ma propre date.

date = dt.date(2018, 10, 30)

query = ''' select * from table where date >= ''' + str(my_date) + ''' order by date '''

Mais, la requête ignore entièrement la condition lors de la saisie de cette façon.

Toutefois, si vous utilisez le signe de pourcentage (%), vous pouvez insérer la date correctement.

Une façon correcte d'écrire la déclaration ci-dessus est:

query = ''' select * from table where date >= ''' + ''' '%s' ''' % my_date + ''' order by date '''

Alors, c'est peut-être utile, ou peut-être pas. J'espère que cela aide au moins une personne dans ma situation!

Meilleurs vœux.

1
spen.smith