Oracle
 sql >> Base de données >  >> RDS >> Oracle

Rechercher une valeur spécifique dans tous les champs de toutes les tables (Oracle)

Citation :

J'ai essayé d'utiliser cette instruction ci-dessous pour trouver une colonne appropriée en fonction de ce que je pense qu'elle devrait être nommée, mais elle n'a renvoyé aucun résultat.*

SELECT * from dba_objects WHERE
object_name like '%DTN%'

Une colonne n'est pas un objet. Si vous voulez dire que vous vous attendez à ce que le nom de la colonne ressemble à '%DTN%', la requête souhaitée est :

SELECT owner, table_name, column_name FROM all_tab_columns WHERE column_name LIKE '%DTN%';

Mais si la chaîne 'DTN' n'est qu'une supposition de votre part, cela ne vous aidera probablement pas.

Au fait, à quel point êtes-vous certain que '1/22/2008P09RR8' est une valeur sélectionnée directement à partir d'une seule colonne ? Si vous ne savez pas du tout d'où il vient, il peut s'agir d'une concaténation de plusieurs colonnes, du résultat d'une fonction ou d'une valeur située dans un objet de table imbriqué. Donc, vous pourriez être sur une chasse à l'oie sauvage en essayant de vérifier chaque colonne pour cette valeur. Ne pouvez-vous pas commencer avec l'application cliente qui affiche cette valeur et essayer de déterminer quelle requête elle utilise pour l'obtenir ?

Quoi qu'il en soit, la réponse de diciu donne une méthode de génération de requêtes SQL pour vérifier chaque colonne de chaque table pour la valeur. Vous pouvez également faire des choses similaires entièrement dans une session SQL en utilisant un bloc PL/SQL et SQL dynamique. Voici un code écrit à la hâte pour cela :

    SET SERVEROUTPUT ON SIZE 100000

    DECLARE
      match_count INTEGER;
    BEGIN
      FOR t IN (SELECT owner, table_name, column_name
                  FROM all_tab_columns
                  WHERE owner <> 'SYS' and data_type LIKE '%CHAR%') LOOP

        EXECUTE IMMEDIATE
          'SELECT COUNT(*) FROM ' || t.owner || '.' || t.table_name ||
          ' WHERE '||t.column_name||' = :1'
          INTO match_count
          USING '1/22/2008P09RR8';

        IF match_count > 0 THEN
          dbms_output.put_line( t.table_name ||' '||t.column_name||' '||match_count );
        END IF;

      END LOOP;

    END;
    /

Il existe également des moyens de le rendre plus efficace.

Dans ce cas, compte tenu de la valeur que vous recherchez, vous pouvez clairement éliminer toute colonne de type NUMBER ou DATE, ce qui réduirait le nombre de requêtes. Peut-être même le restreindre aux colonnes dont le type est comme '%CHAR%'.

Au lieu d'une requête par colonne, vous pouvez créer une requête par table comme ceci :

SELECT * FROM table1
  WHERE column1 = 'value'
     OR column2 = 'value'
     OR column3 = 'value'
     ...
     ;