web-dev-qa-db-fra.com

Fonction de déclenchement PostgreSQL qui sélectionne de% actuel% Tableau

J'ai plusieurs tables qui ont les mêmes noms de colonnes, ils varient que dans leurs valeurs de colonne, comme:

tbl_log_a
tbl_log_b
tbl_log_c
...

26 tables de A à Z. Chaque table a une gâchette qui appelle une fonction de déclenchement qui fait exactement la même chose:

SELECT columnname FROM tbl_log_a

Autre que cela, toutes mes fonctions de déclenchement font exactement la même chose. Ils diffèrent en ce qu'ils:

select columnname FROM tbl_log_a
select columnname FROM tbl_log_b
select columnname FROM tbl_log_c
...

Donc, je dois créer 26 fonctions de déclenchement, une pour chaque tbl_log_%letter%. Existe-t-il un moyen de dire à la fonction de déclenchement de:

SELECT columnname FROM %currenttable%

Par %currenttable% Je veux dire la table où la gâchette est placée. Ou alors:

SELECT columnname FROM tbl_log_%letter%

Est-ce possible dans Postgres 9.1? Je lis sur des tables déterminées dynamiquement. N'importe quel indice? Je souhaite stocker le nom de la table elle-même à l'intérieur d'une variable, pas les colonnes à l'intérieur de cette table, car la fonction de déclenchement fonctionne sur plusieurs colonnes à l'intérieur de cette table.

TG_TABLE_NAME
TG_TABLE_SCHEMA
4
Natysiu16

J'ai suggéré que vous utilisiez des arguments de déclenchement, mais ce n'est pas nécessaire. Vous pouvez utiliser les variables automatiquesTG_TABLE_SCHEMA Et TG_TABLE_NAME Ou utilisez TG_RELID. Celles-ci, à côté de EXECUTE pour SQL dynamique, vous permettent de faire ce que vous voulez:

BEGIN
    EXECUTE format('SELECT colname FROM %I', TG_RELID)
END;

ou alors

BEGIN
    EXECUTE format('SELECT colname FROM %I.%I', TG_TABLE_SCHEMA, TG_TABLE_NAME)
END;

(Bien sûr, ceux-ci ne fonctionneront pas aussi, car le SELECT n'a aucune destination pour les données. Vous devez utiliser EXECUTE format(..) INTO ... pour stocker le résultat dans un DECLAREd variable), par exemple.

DECLARE
    _colvar integer;
BEGIN
    EXECUTE format('SELECT colname FROM %I.%I', TG_TABLE_SCHEMA, TG_TABLE_NAME) INTO _colvar;
    RAISE NOTICE 'colname value was %',_colvar;
END;
5
Craig Ringer

La syntaxe réelle correspondant à l'imaginaire SELECT columnname FROM %currenttable% serait, dans PLPGSQL:

execute format('SELECT columnname FROM %I.%I',
                TG_TABLE_SCHEMA, TG_TABLE_NAME);

Les variables intégrées TG_ * sont documentées dans Procédures de déclenchement et execute et format PLPGSQL construit dans déclarations de base .

La requête ci-dessus est absurde par elle-même (elle sélectionne des résultats qui vont nulle part); L'intention est de montrer la syntaxe de base sur laquelle une requête réelle pourrait être construite.

2
Daniel Vérité

Ou vous pouvez utiliser TG_RELID, mais depuis son type de données est uni oid, pas regclass, il faut le jeter sur regclass explicitement pour obtenir l'auto -conversion à un schéma qualifié (seulement si le courant search_path le requiert), nom de table bien échappé. la documentation :

TG_RELID

Type de données oid; L'ID d'objet de la table qui a provoqué l'invocation de la gâchette.

Mine d'accompagnement audacieux. Je me demande pourquoi ils ne l'ont pas fait regclass pour commencer avec ...

EXECUTE format('SELECT columnname FROM %s', TG_RELID::regclass);

Et il n'est toujours pas clair ce que vous faites avec le résultat. Typiquement, vous utiliseriez cela dans un INSERT/UPDATE/DELETE instruction ou écrire le résultat à une variable :

EXECUTE format('SELECT columnname FROM %s', TG_RELID::regclass)
INTO my_variable;

Seule la première valeur est attribuée. Si SELECT trouve plus de lignes, le reste est jeté. Vous voudrez peut-être ajouter ORDER BY ... LIMIT 1.

En rapport:

2
Erwin Brandstetter