En écrivant une fonction pour tester si une colonne col_name
Existe dans une table _tbl
, Je voudrais extraire le nom du schéma de la table, qui est passé dans la fonction en tant que regclass
paramètre (pour la sécurité ??).
CREATE OR REPLACE FUNCTION column_exists(_tbl regclass, col_name text)
RETURNS bool AS
$func$
SELECT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema=get_schema($1)
AND table_name=get_table($1)
AND column_name=$2
);
$func$ LANGUAGE sql;
Donc, si le nom de la table est 'staging.my_table'::regclass
, J'aimerais obtenir staging
d'une fonction imaginaire get_schema
.
Puis-je simplement implémenter cette fonction avec par exemple split_part(_tbl::text, '.', 1)
?
De plus, est-il garanti que le nom de la table _tbl
, Une fois converti en texte, aura toujours un nom de schéma? (C'est-à-dire en n'omettant pas des choses comme public.
))
Je ne connais pas très bien le type regclass
. J'ai cherché mais je n'ai pas trouvé comment extraire le nom du schéma, et je voulais juste demander avant de réinventer les roues.
Puis-je simplement implémenter cette fonction avec par exemple
split_part(_tbl::text, '.', 1)
?
Je ne suis pas sûr que ce serait sûr. Au lieu de cela, j'utiliserais,
SELECT nspname
FROM pg_catalog.pg_class AS c
JOIN pg_catalog.pg_namespace AS ns
ON c.relnamespace = ns.oid
WHERE c.oid = _tbl;
Cela est garanti de fonctionner.
En écrivant une fonction pour tester si une colonne
col_name
existe dans une table_tbl
, Je voudrais extraire le nom du schéma de la table, qui est passé dans la fonction en tant que paramètre regclass (pour la sécurité ??).
Vous pourriez donc faire quelque chose comme,
SELECT nspname
FROM pg_catalog.pg_attribute AS a
JOIN pg_catalog.pg_class AS c
ON a.attrelid = c.oid
JOIN pg_catalog.pg_namespace AS ns
ON c.relnamespace = ns.oid
WHERE c.oid = _tbl
AND a.attname = col_name;
Si vous avez un identifiant complet, un avec le nom de la table et le nom du schéma à l'intérieur, vous pouvez utiliser parse_ident
pour l'analyser en toute sécurité.
Pour simplifier davantage, vous pouvez utiliser un transtypage en regnamespace
- un autre type d'identifiant d'objet introduit avec Postgres 9.5
SELECT relnamespace::regnamespace::text
FROM pg_catalog.pg_class
WHERE oid = _tbl;
La conversion d'un type d'identifiant d'objet en text
produit une chaîne entièrement qualifiée (uniquement si search_path
L'exige) et entre guillemets doubles (uniquement si nécessaire).
Mais vous n'avez pas besoin de tout cela si vous travaillez directement avec pg_attribute
:
CREATE OR REPLACE FUNCTION pg_temp.column_exists(_tbl regclass, _col_name text)
RETURNS bool AS
$func$
SELECT EXISTS (
SELECT FROM pg_catalog.pg_attribute
WHERE attrelid = _tbl
AND attname = _col_name
);
$func$ LANGUAGE sql;
Plus simple, plus court, plus rapide.