sql >> Database >  >> RDS >> Oracle

Doorzoek alle velden in alle tabellen voor een specifieke waarde (Oracle)

Citaat:

Ik heb geprobeerd deze verklaring hieronder te gebruiken om een ​​geschikte kolom te vinden op basis van wat ik denk dat het zou moeten heten, maar het leverde geen resultaten op.*

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

Een kolom is geen object. Als u bedoelt dat u verwacht dat de kolomnaam zal zijn als '%DTN%', is de gewenste zoekopdracht:

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

Maar als de 'DTN'-string slechts een gok van jouw kant is, zal dat waarschijnlijk niet helpen.

Trouwens, hoe zeker bent u ervan dat '1/22/2008P09RR8' een waarde is die rechtstreeks uit een enkele kolom is geselecteerd? Als u helemaal niet weet waar het vandaan komt, kan het een aaneenschakeling van meerdere kolommen zijn, of het resultaat van een functie, of een waarde in een genest tabelobject. Het kan dus zijn dat u op een wilde gansjacht bent en probeert elke kolom op die waarde te controleren. Kun je niet beginnen met welke clienttoepassing dan ook die deze waarde weergeeft en proberen te achterhalen welke query het gebruikt om deze te verkrijgen?

Hoe dan ook, het antwoord van diciu geeft één methode om SQL-query's te genereren om elke kolom van elke tabel op de waarde te controleren. U kunt soortgelijke dingen ook volledig in één SQL-sessie doen met behulp van een PL/SQL-blok en dynamische SQL. Hier is wat haastig geschreven code daarvoor:

    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;
    /

Er zijn enkele manieren waarop u het ook efficiënter kunt maken.

In dit geval kunt u, gezien de waarde die u zoekt, duidelijk elke kolom verwijderen die van het type NUMBER of DATE is, wat het aantal zoekopdrachten zou verminderen. Misschien zelfs beperken tot kolommen waarvan het type '%CHAR%' is.

In plaats van één zoekopdracht per kolom, zou u als volgt één zoekopdracht per tabel kunnen maken:

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


  1. PostgreSQL CSV importeren vanaf de opdrachtregel

  2. Rijen retourneren die niet-alfanumerieke tekens bevatten in SQL Server

  3. Wanneer moet ik de DatabaseHelper sluiten?

  4. Som over waarden per maand in milliseconden