J'essaie d'exécuter la commande SQL ci-dessous:
SELECT ARRAY(
SELECT column_name
FROM information_schema.columns
WHERE table_name ='gis_field_configuration_stage'
);
et je reçois l'erreur ci-dessous:
ERROR: could not find array type for datatype information_schema.sql_identifier
Juste jeter column_name
à text
pour contourner l'erreur:
SELECT ARRAY(
SELECT column_name::text
FROM information_schema.columns
WHERE table_name ='gis_field_configuration_stage'
);
Son type d'origine est information_schema.sql_identifier
Et son arrive qu'un tableau de ce type n'est pas fourni dans les types prédéfinis.
Un nom de table est pas Un identifiant unique. Un tableau du même nom pourrait exister dans un autre schéma.
Cela peut fonctionner très bien pour utiliser des noms de table dans vos questions sans schéma - les qualifier. Tant que votre search_path
est défini correctement, les bonnes tables seront cueillies.
Mais cela ne vous aidera pas à interroger des tables de catalogue! Si d'autres tables du même nom existent, vous récupérez toutes les colonnes de toutes ces tables et que vous ne le remarquerez même pas. Ajoutez le nom du schéma pour le rendre unique:
SELECT ARRAY(
SELECT column_name::text
FROM information_schema.columns
WHERE table_name ='gis_field_configuration_stage'
AND table_schema ='public' -- or whatever the schema is
)
information_schema
est lentinformation_schema
est seulement bon pour la portabilité des plats de plâtre (qui ne fonctionne presque jamais de toute façon). La vue dans information_schema
sont monstrueux et lents. Si vous n'avez pas l'intention de le porter sur un autre RDBMS dans le futur, et si vous n'utilisez pas de fonctionnalités exotiques susceptibles de changer entre les versGRES, l'utilisation pg_catalog.pg_attribute
à la place. Postgres est pas Va changer pg_attribute
D'une manière qui invaliderait cette requête équivalente:
SELECT ARRAY(
SELECT attname
FROM pg_catalog.pg_attribute
WHERE attrelid = 'public.tbl'::regclass
AND NOT attisdropped
AND attnum > 0
);
Autour 100 fois Plus vite dans mes tests.
regclass
est sûrCela a un autre avantage important: si vous en erreur un nom de table ou que cela n'existe pas pour une autre raison de la première requête, il ne trouvera pas de colonnes. Le résultat peut être trompeur et vous ne le saurez jamais. Si vous lancez la table comme si je démontre ('public.tbl'::regclass
), vous obtenez un message d'erreur si le tableau ne doit pas exister. plus sur les types d'identifiant d'objet dans le manuel.
Vous pourriez même utiliser 'tbl'::regclass
, parce que le search_path
est utilisé pour l'évaluation de cette expression. Si votre requête de base fonctionne sans qualification de schéma, cela aussi. Il est toujours plus sûr d'ajouter le schéma.
En rapport:
L'approche de votre commentaire est invalide pour commencer par.
[.____] ARRAY[...] NOT IN ARRAY[...]
n'a pas de sens à Postgres.
Si vous voulez vous assurer que deux tables ne partagent pas tout Noms de colonne :
SELECT *
FROM tbl
WHERE NOT EXISTS (
SELECT 1
FROM pg_catalog.pg_attribute a1
JOIN pg_catalog.pg_attribute a2 USING (attname)
WHERE a1.attrelid = 'public.tbl'::regclass
AND NOT a1.attisdropped
AND a1.attnum > 0
AND a2.attrelid = 'public.tbl2'::regclass
AND NOT a2.attisdropped
AND a2.attnum > 0
);
Si vous voulez vous assurer que deux tables ne partagent pas tout leurs noms de colonne :
SELECT *
FROM tbl
WHERE EXISTS (
SELECT 1
FROM (
SELECT attname
FROM pg_catalog.pg_attribute
WHERE attrelid = 'public.tbl'::regclass
AND NOT attisdropped
AND attnum > 0
) a1
FULL OUTER JOIN (
SELECT attname
FROM pg_catalog.pg_attribute
WHERE attrelid = 'public.tbl2'::regclass
AND NOT attisdropped
AND attnum > 0
) a2 USING (attname)
WHERE a1.attname IS NULL OR
a2.attname IS NULL
);