Comment rechercher une valeur spécifique dans tous les tableaux (PostgreSQL)?
Est-il possible de rechercher chaque colonne de chaque table pour une valeur particulière dans PostgreSQL?
Une question similaire qui est disponible ici pour Oracle.
- Vous êtes à la recherche d'un outil ou d'une mise en œuvre des procédures indiquées dans la question?
- Non, juste la façon la plus simple pour trouver une valeur spécifique dans tous les champs/tables.
- Si vous ne voulez pas utiliser un outil externe?
- Si c'est le moyen le plus simple => ok pour un outil externe 🙂
Vous devez vous connecter pour publier un commentaire.
Que diriez-verser le contenu de la base de données, puis à l'aide
grep
?Le même utilitaire pg_dump, peut inclure des noms de colonne dans la sortie. Il suffit de changer
--inserts
à--column-inserts
. De cette façon, vous pouvez rechercher des noms de colonne, trop. Mais si j'étais à la recherche pour les noms de colonne, je serais probablement vider le schéma à la place des données.ALTER DATABASE your_db_name SET bytea_output = 'escape';
sur la base de données (ou une copie de celui-ci) avant de les déverser. (Je ne suis pas voyant un moyen de spécifier ce juste pour unpg_dump
de commande.)Voici une de fonctions pl/pgsql qui localise les dossiers où une colonne contient une valeur spécifique.
Il prend comme arguments la valeur à rechercher dans le format de texte, un tableau de noms de table à rechercher dans (par défaut, toutes les tables) et un tableau de noms de schéma (par défaut tous les noms de schéma).
Elle retourne un tableau de structure avec le schéma, le nom de la table, le nom de la colonne et de la pseudo-colonne
ctid
(non-durable de l'emplacement physique de la ligne dans le tableau, voir Système De Colonnes)MODIFIER: ce code est pour PG 9.1 ou une version plus récente. Aussi, vous voudrez peut-être la version sur github sur le même principe, mais en ajoutant un peu de vitesse et d'amélioration du reporting.
Des exemples d'utilisation dans une base de données de test:
De recherche dans tous les tableaux figurant dans le schéma public:
Recherche dans une table spécifique:
De recherche dans un sous-ensemble de tableaux obtenus à partir d'une sélection:
Obtenir une ligne de résultat correspondant à la table de base et et ctid:
Pour tester de nouveau une expression régulière au lieu de stricte égalité, comme grep, ce:
peut être changé:
Le seul outil que je connais qui peut le faire est: SQL Workbench/J: http://www.sql-workbench.net/
Java/JDBC en fonction de l'outil qui offre un particulier (propriétaire) SQL "commande" à la recherche par le biais de tous (ou seulement certains) des tables dans une base de données:
http://www.sql-workbench.eu/manual/wb-commands.html#command-search-data
http://www.sql-workbench.eu/wbgrepdata_png.html
Et si quelqu'un pense que cela pourrait aider. Voici @Daniel-Vérité de la fonction, avec un autre param qui acceptent des noms de colonnes qui peuvent être utilisés dans la recherche. De cette manière, il diminue le temps de traitement. Au moins dans mon test il réduit beaucoup.
Soufflet est un exemple d'utilisation de la search_function créé ci-dessus.
Sans stockage d'une nouvelle procédure, vous pouvez utiliser un bloc de code et l'exécuter pour obtenir une table de faits. Vous pouvez filtrer les résultats par schéma, de table ou de colonne nom.
Cela ne définit pas la façon de faire correspondre exactement.
Ni faut-il définir ce qu'il doit retourner exactement.
En supposant que:
regclass
) et le pointeur d'élément (ctid
), parce que c'est plus simple.Voici une mort simple, rapide et légèrement sale:
Appel:
Fournir le motif de recherche, sans enfermer
%
.Pourquoi légèrement sale?
Si des séparateurs et des décorateurs pour la ligne
text
représentation peut être une partie du modèle de recherche, il peut y avoir des faux positifs:,
par défaut()
"
\
peut être ajouté que l'évasion charEt le texte de la représentation de certaines colonnes peuvent locales dépendent de paramètres - mais cette ambiguïté est inhérente à la question, pas à ma solution.
Chaque ligne éligible est retourné une fois, même lorsqu'elle correspond à plusieurs reprises (par opposition à d'autres réponses ici).
Cette recherche l'ensemble de la DB, sauf pour les catalogues système. Généralement prendre beaucoup de temps pour terminer. Vous pouvez restreindre à certains schémas, tableaux (ou même des colonnes) comme démontré dans d'autres réponses. Ou ajouter des notes et un indicateur de progrès, a également démontré dans une autre réponse.
La
regclass
identificateur d'objet type est représenté comme nom de table, de schéma-qualifiés, si nécessaire, pour lever l'ambiguïté, selon l'actuelsearch_path
:Quel est le
ctid
?Vous pourriez vouloir pour échapper les caractères ayant une signification particulière dans le modèle de recherche. Voir:
Voici @Daniel-Vérité de la fonction avec les progrès de la fonctionnalité de reporting.
Il rend compte de l'avancement de trois façons:
{nombre total de colonnes à rechercher dans} 0;
situé dans c:\windows\temp\{progress_seq}.txt.
_
-- Au-dessous de la fonction liste de toutes les tables qui contiennent une chaîne de caractères dans la base de données
--Parcourt toutes les tables dans la base de données
-- Retourne le nombre de tables pour laquelle la condition est remplie.
-- Par exemple, si le texte existe dans l'un des champs de la table,
-- ensuite le compte sera supérieure à 0. Nous pouvons trouver les notifications
- dans la section Messages du résultat spectateur dans la base de données postgres.
--Obtenir les champs de chaque table. Construit la clause where avec toutes les colonnes d'une table.
Il y a un moyen d'atteindre cet objectif sans la création d'une fonction ou à l'aide d'un outil externe. En utilisant Postgres'
query_to_xml()
fonction qui peut dynamiquement à l'exécution d'une requête à l'intérieur d'une autre requête, il est possible de rechercher un texte dans de nombreux tableaux. Ceci est basé sur ma réponse pour récupérer le nombre de lignes de toutes les tables:À la recherche de la chaîne
foo
sur toutes les tables dans un schéma, les éléments suivants peuvent être utilisés:Noter que l'utilisation de
xmltable
nécessite Postgres 10 ou plus récent. Pour les anciennes version de Postgres, ceci peut également se faire à l'aide de xpath().L'expression de table commune (
WITH ...
) est utilisé uniquement à des fins de commodité. Il parcourt toutes les tables dans lapublic
schéma. Pour chaque table, la requête suivante est exécutée par le biais de laquery_to_xml()
fonction:La clause where est utilisée pour s'assurer que le cher génération de contenu XML n'est fait que pour les lignes qui contiennent la chaîne de recherche. Cela pourrait revenir à quelque chose comme ceci:
La conversion de la rangée complète de
jsonb
est fait, afin que dans la suite on a pu voir dont la valeur appartient à la colonne.Ci-dessus pourrait revenir à quelque chose comme ceci:
En ligne exemple pour Postgres 10+
En ligne exemple pour les anciennes versions Postgres