Durchsuchen Sie alle Felder in allen Tabellen nach einem bestimmten Wert (Oracle).


115

Ist es möglich, jedes Feld jeder Tabelle nach einem bestimmten Wert in Oracle zu durchsuchen?

Es gibt Hunderte von Tabellen mit Tausenden von Zeilen in einigen Tabellen, daher weiß ich, dass das Abfragen sehr lange dauern kann. Ich weiß jedoch nur, dass ein Wert für das Feld, für das ich eine Abfrage durchführen möchte, lautet1/22/2008P09RR8 . <

Ich habe versucht, diese Anweisung unten zu verwenden, um eine geeignete Spalte zu finden, die meiner Meinung nach benannt werden sollte, aber es wurden keine Ergebnisse zurückgegeben.

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

Es gibt absolut keine Dokumentation in dieser Datenbank und ich habe keine Ahnung, woher dieses Feld stammt.

Irgendwelche Gedanken?


Können wir dies mit einer einzelnen Abfrage anstelle einer gespeicherten Prozedur tun?
Freakyuser


@LalitKumarB Auf die von Ihnen aufgelistete Seite kann nicht mehr zugegriffen werden. Wäre es möglich, einige Informationen als Antwort zu veröffentlichen?
Dodzi Dzakuma

@DodziDzakuma Die Seite ist zugänglich lalitkumarb.wordpress.com/2015/01/06/… Auch ich habe eine Antwort gepostet, bitte scrollen Sie nach unten oder sehen Sie stackoverflow.com/a/27794127/3989608
Lalit Kumar B

Wenn Sie Probleme haben, die Lalit Kumar-Abfrage herauszufinden, versuchen Sie diese Demo: sqlfiddle.com/#!4/76924c/2/0
DxTx

Antworten:


93

Zitat:

Ich habe versucht, diese Anweisung unten zu verwenden, um eine geeignete Spalte zu finden, die meiner Meinung nach benannt werden sollte, aber es wurden keine Ergebnisse zurückgegeben. *

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

Eine Spalte ist kein Objekt. Wenn Sie meinen, dass der Spaltenname '% DTN%' lautet, lautet die gewünschte Abfrage:

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

Aber wenn die 'DTN'-Zeichenfolge nur eine Vermutung von Ihrer Seite ist, wird das wahrscheinlich nicht helfen.

Wie sicher sind Sie übrigens, dass '1/22 ​​/ 2008P09RR8' ein Wert ist, der direkt aus einer einzelnen Spalte ausgewählt wird? Wenn Sie überhaupt nicht wissen, woher es kommt, kann es sich um eine Verkettung mehrerer Spalten oder um das Ergebnis einer Funktion oder um einen Wert handeln, der sich in einem verschachtelten Tabellenobjekt befindet. Sie könnten also auf einer wilden Gänsejagd sein und versuchen, jede Spalte auf diesen Wert zu überprüfen. Können Sie nicht mit einer Clientanwendung beginnen, die diesen Wert anzeigt, und versuchen, herauszufinden, mit welcher Abfrage sie abgerufen wird?

Wie auch immer, die Antwort von diciu bietet eine Methode zum Generieren von SQL-Abfragen, um jede Spalte jeder Tabelle auf den Wert zu überprüfen. Sie können ähnliche Aufgaben auch vollständig in einer SQL-Sitzung mit einem PL / SQL-Block und dynamischem SQL ausführen. Hier ist ein hastig geschriebener Code dafür:

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

Es gibt einige Möglichkeiten, wie Sie es auch effizienter gestalten können.

In diesem Fall können Sie angesichts des gesuchten Werts jede Spalte vom Typ NUMBER oder DATE eindeutig entfernen, wodurch die Anzahl der Abfragen verringert wird. Vielleicht beschränken Sie es sogar auf Spalten, in denen der Typ '% CHAR%' ist.

Anstelle einer Abfrage pro Spalte können Sie eine Abfrage pro Tabelle wie folgt erstellen:

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

Sie sollten es auf die Spalten char, varchar und varchar2 beschränken, da die Spalten number und date diese Zeichenfolge möglicherweise nicht enthalten können.
Erich Kitzmüller

8
@ammoQ - wie ich im vorletzten Absatz sagte?
Dave Costa

Ich habe dies auf 9i ausgeführt und erhalte den unbekannten Spaltennamen. Kann mir jemand sagen, welche Änderungen erforderlich sind, um dies auf 9i auszuführen?
Regmi

@ Regmi - Entschuldigung, das war tatsächlich ein Fehler in meinem Code, kein Versionsproblem. Die Schleife sollte von all_tab_columnsnicht gefahren worden sein all_tables. Ich habe es behoben.
Dave Costa

@ DaveCosta - Vielen Dank für die Korrektur, aber ich erhalte immer noch den Fehler "Tabelle oder Ansicht existiert nicht" in Zeile 6. Zeile 6 lautet "Sofort ausführen".
Regmi

34

Ich habe den obigen Code geändert, damit er schneller funktioniert, wenn Sie nur in einem Eigentümer suchen. Sie müssen nur die 3 Variablen v_owner, v_data_type und v_search_string ändern, um sie an Ihre Suche anzupassen.

SET SERVEROUTPUT ON SIZE 100000

DECLARE
  match_count INTEGER;
-- Type the owner of the tables you are looking at
  v_owner VARCHAR2(255) :='ENTER_USERNAME_HERE';

-- Type the data type you are look at (in CAPITAL)
-- VARCHAR2, NUMBER, etc.
  v_data_type VARCHAR2(255) :='VARCHAR2';

-- Type the string you are looking at
  v_search_string VARCHAR2(4000) :='string to search here...';

BEGIN
  FOR t IN (SELECT table_name, column_name FROM all_tab_cols where owner=v_owner and data_type = v_data_type) LOOP

    EXECUTE IMMEDIATE 
    'SELECT COUNT(*) FROM '||t.table_name||' WHERE '||t.column_name||' = :1'
    INTO match_count
    USING v_search_string;

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

  END LOOP;
END;
/

Ich musste die erste Zeile kommentieren, um diese Abfrage ausführen zu können. Außerdem konnte ich den Eigentümerfilter nicht entfernen und die Abfrage ausführen.
Popa Andrei

1
Ich musste den Tabellennamen / Spaltennamen in doppelte Anführungszeichen setzen, um Probleme zu vermeiden, wenn diese zitiert werden müssen:'SELECT COUNT(*) FROM "'||t.table_name||'" WHERE "'||t.column_name||'" = :1'
Steve Chambers

Beachten Sie, dass all_tab_cols trotz des Namens auch Ansichten enthält
phil_w

was genau ist dbms_output? Weil die Abfragen erfolgreich in DataGrip ausgeführt werden, aber ich sehe kein Ergebnis danach.
Misteeque

Ich weiß, dass dies ein bisschen alt ist, aber wenn ich dies ausführe, erhalte ich nur eine Skriptausgabe von "anonymer Block abgeschlossen"
JasonWH

7

Hier ist eine weitere modifizierte Version, die eine niedrigere Teilzeichenfolgenübereinstimmung vergleicht. Dies funktioniert in Oracle 11g.

DECLARE
  match_count INTEGER;
-- Type the owner of the tables you are looking at
  v_owner VARCHAR2(255) :='OWNER_NAME';

-- Type the data type you are look at (in CAPITAL)
-- VARCHAR2, NUMBER, etc.
  v_data_type VARCHAR2(255) :='VARCHAR2';

-- Type the string you are looking at
  v_search_string VARCHAR2(4000) :='%lower-search-sub-string%';

BEGIN
  FOR t IN (SELECT table_name, column_name FROM all_tab_cols where owner=v_owner and data_type = v_data_type) LOOP

    EXECUTE IMMEDIATE 
    'SELECT COUNT(*) FROM '||t.table_name||' WHERE lower('||t.column_name||') like :1'
    INTO match_count
    USING v_search_string;

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

  END LOOP;
END;
/

7

Ja, das können Sie und Ihr DBA wird Sie hassen und Sie finden, dass Sie Ihre Schuhe auf den Boden nageln, da dies viele E / A-Vorgänge verursacht und die Datenbankleistung beim Löschen des Caches erheblich beeinträchtigt.

select column_name from all_tab_columns c, user_all_tables u where c.table_name = u.table_name;

für den Anfang.

Ich würde mit den laufenden Abfragen beginnen, indem ich das v$sessionund das verwende v$sqlarea. Dies ändert sich basierend auf der Oracle-Version. Dies wird den Raum einschränken und nicht alles treffen.


7

Ich weiß, dass dies ein altes Thema ist. Aber ich sehe einen Kommentar zu der Frage, ob dies in SQLstatt in Verwendung getan werden könnte PL/SQL. Also dachte ich mir eine Lösung zu posten.

Die folgende Demonstration dient zur Suche nach einem Wert in allen Spalten aller Tabellen in einem gesamten Schema :

  • Suchen Sie einen CHARACTER-Typ

Lassen Sie uns nach dem Wert KINGim SCOTTSchema suchen .

SQL> variable val varchar2(10)
SQL> exec :val := 'KING'

PL/SQL procedure successfully completed.

SQL> SELECT DISTINCT SUBSTR (:val, 1, 11) "Searchword",
  2    SUBSTR (table_name, 1, 14) "Table",
  3    SUBSTR (column_name, 1, 14) "Column"
  4  FROM cols,
  5    TABLE (xmlsequence (dbms_xmlgen.getxmltype ('select '
  6    || column_name
  7    || ' from '
  8    || table_name
  9    || ' where upper('
 10    || column_name
 11    || ') like upper(''%'
 12    || :val
 13    || '%'')' ).extract ('ROWSET/ROW/*') ) ) t
 14  ORDER BY "Table"
 15  /

Searchword  Table          Column
----------- -------------- --------------
KING        EMP            ENAME

SQL>
  • Suchen Sie einen NUMERIC-Typ

Lassen Sie uns nach dem Wert 20im SCOTTSchema suchen .

SQL> variable val NUMBER
SQL> exec :val := 20

PL/SQL procedure successfully completed.

SQL> SELECT DISTINCT SUBSTR (:val, 1, 11) "Searchword",
  2    SUBSTR (table_name, 1, 14) "Table",
  3    SUBSTR (column_name, 1, 14) "Column"
  4  FROM cols,
  5    TABLE (xmlsequence (dbms_xmlgen.getxmltype ('select '
  6    || column_name
  7    || ' from '
  8    || table_name
  9    || ' where upper('
 10    || column_name
 11    || ') like upper(''%'
 12    || :val
 13    || '%'')' ).extract ('ROWSET/ROW/*') ) ) t
 14  ORDER BY "Table"
 15  /

Searchword  Table          Column
----------- -------------- --------------
20          DEPT           DEPTNO
20          EMP            DEPTNO
20          EMP            HIREDATE
20          SALGRADE       HISAL
20          SALGRADE       LOSAL

SQL>

6
hrmm .... mit xml sieht aus wie übertrieben. Außerdem:Error occurred in XML processing ORA-00932: inconsistent datatypes: expected NUMBER got BLOB
Towi

2
ORA-19202: Fehler bei der XML-Verarbeitung aufgetreten ORA-00932: Inkonsistente Datentypen: erwartet CHAR hat BLOB ORA-06512: bei "SYS.DBMS_XMLGEN", Zeile 288 ORA-06512: bei Zeile 1 19202. 00000 - "Fehler bei der XML-Verarbeitung aufgetreten % s "* Ursache: Bei der Verarbeitung der XML-Funktion ist ein Fehler aufgetreten. * Maßnahme: Überprüfen Sie die angegebene Fehlermeldung und beheben Sie das entsprechende Problem
Mohammad Faisal

Irgendwelche Ideen? ORA-19202: Fehler bei der XML-Verarbeitung aufgetreten ORA-22813: Operandenwert überschreitet Systemgrenzen ORA-06512: bei "SYS.DBMS_XMLGEN", Zeile 288 ORA-06512: bei Zeile 1
Menios

5

Ich würde so etwas tun (generiert alle Auswahlen, die Sie benötigen). Sie können sie später an sqlplus weiterleiten:

echo "select table_name from user_tables;" | sqlplus -S user/pwd | grep -v "^--" | grep -v "TABLE_NAME" | grep "^[A-Z]" | while read sw;
do echo "desc $sw" | sqlplus -S user/pwd | grep -v "\-\-\-\-\-\-" | awk -F' ' '{print $1}' | while read nw;
do echo "select * from $sw where $nw='val'";
done;
done;

Es ergibt:

select * from TBL1 where DESCRIPTION='val'
select * from TBL1 where ='val'
select * from TBL2 where Name='val'
select * from TBL2 where LNG_ID='val'

Und was es tut, ist - für jedes table_namevon user_tablesjedes Feld abrufen (von desc) und eine Auswahl * aus der Tabelle erstellen, wobei das Feld gleich 'val' ist.


5

Ich habe das Skript von Flood so geändert, dass es für jede Tabelle einmal ausgeführt wird und nicht für jede Spalte jeder Tabelle, um die Ausführung zu beschleunigen. Es erfordert Oracle 11g oder höher.

    set serveroutput on size 100000

declare
    v_match_count integer;
    v_counter integer;

    -- The owner of the tables to search through (case-sensitive)
    v_owner varchar2(255) := 'OWNER_NAME';
    -- A string that is part of the data type(s) of the columns to search through (case-insensitive)
    v_data_type varchar2(255) := 'CHAR';
    -- The string to be searched for (case-insensitive)
    v_search_string varchar2(4000) := 'FIND_ME';

    -- Store the SQL to execute for each table in a CLOB to get around the 32767 byte max size for a VARCHAR2 in PL/SQL
    v_sql clob := '';
begin
    for cur_tables in (select owner, table_name from all_tables where owner = v_owner and table_name in 
                       (select table_name from all_tab_columns where owner = all_tables.owner and data_type like '%' ||  upper(v_data_type) || '%')
                       order by table_name) loop
        v_counter := 0;
        v_sql := '';

        for cur_columns in (select column_name from all_tab_columns where 
                            owner = v_owner and table_name = cur_tables.table_name and data_type like '%' || upper(v_data_type) || '%') loop
            if v_counter > 0 then
                v_sql := v_sql || ' or ';
            end if;
            v_sql := v_sql || 'upper(' || cur_columns.column_name || ') like ''%' || upper(v_search_string) || '%''';
            v_counter := v_counter + 1;
        end loop;

        v_sql := 'select count(*) from ' || cur_tables.table_name || ' where ' || v_sql;

        execute immediate v_sql
        into v_match_count;

        if v_match_count > 0 then
            dbms_output.put_line('Match in ' || cur_tables.owner || ': ' || cur_tables.table_name || ' - ' || v_match_count || ' records');
        end if;
    end loop;

    exception
        when others then
            dbms_output.put_line('Error when executing the following: ' || dbms_lob.substr(v_sql, 32600));
end;
/

5

Ich hatte folgende Probleme mit der Antwort von @Lalit Kumars:

ORA-19202: Error occurred in XML processing
ORA-00904: "SUCCESS": invalid identifier
ORA-06512: at "SYS.DBMS_XMLGEN", line 288
ORA-06512: at line 1
19202. 00000 -  "Error occurred in XML processing%s"
*Cause:    An error occurred when processing the XML function
*Action:   Check the given error message and fix the appropriate problem

Lösung ist:

WITH  char_cols AS
  (SELECT /*+materialize */ table_name, column_name
   FROM   cols
   WHERE  data_type IN ('CHAR', 'VARCHAR2'))
SELECT DISTINCT SUBSTR (:val, 1, 11) "Searchword",
       SUBSTR (table_name, 1, 14) "Table",
       SUBSTR (column_name, 1, 14) "Column"
FROM   char_cols,
       TABLE (xmlsequence (dbms_xmlgen.getxmltype ('select "'
       || column_name
       || '" from "'
       || table_name
       || '" where upper("'
       || column_name
       || '") like upper(''%'
       || :val
       || '%'')' ).extract ('ROWSET/ROW/*') ) ) t
ORDER  BY "Table"
/ 

4

Wenn wir die Tabellen- und Spaltennamen kennen, aber herausfinden möchten, wie oft eine Zeichenfolge für jedes Schema angezeigt wird:

Declare

owner VARCHAR2(1000);
tbl VARCHAR2(1000);
cnt number;
ct number;
str_sql varchar2(1000);
reason varchar2(1000);
x varchar2(1000):='%string_to_be_searched%';

cursor csr is select owner,table_name 
from all_tables where table_name ='table_name';

type rec1 is record (
ct VARCHAR2(1000));

type rec is record (
owner VARCHAR2(1000):='',
table_name VARCHAR2(1000):='');

rec2 rec;
rec3 rec1;
begin

for rec2 in csr loop

--str_sql:= 'select count(*) from '||rec.owner||'.'||rec.table_name||' where CTV_REMARKS like '||chr(39)||x||chr(39);
--dbms_output.put_line(str_sql);
--execute immediate str_sql

execute immediate 'select count(*) from '||rec2.owner||'.'||rec2.table_name||' where column_name like '||chr(39)||x||chr(39)
into rec3;
if rec3.ct <> 0 then
dbms_output.put_line(rec2.owner||','||rec3.ct);
else null;
end if;
end loop;
end;

2

Verfahren zum Durchsuchen der gesamten Datenbank:

    CREATE or REPLACE PROCEDURE SEARCH_DB(SEARCH_STR IN VARCHAR2, TAB_COL_RECS OUT VARCHAR2) IS
      match_count integer;
      qry_str varchar2(1000);
      CURSOR TAB_COL_CURSOR IS 
          SELECT TABLE_NAME,COLUMN_NAME,OWNER,DATA_TYPE FROM ALL_TAB_COLUMNS WHERE DATA_TYPE in ('NUMBER','VARCHAR2') AND OWNER='SCOTT';
          BEGIN  
            FOR TAB_COL_REC  IN TAB_COL_CURSOR
            LOOP
              qry_str := 'SELECT COUNT(*) FROM '||TAB_COL_REC.OWNER||'.'||TAB_COL_REC.TABLE_NAME|| 
              ' WHERE '||TAB_COL_REC.COLUMN_NAME;
               IF TAB_COL_REC.DATA_TYPE = 'NUMBER' THEN
                      qry_str := qry_str||'='||SEARCH_STR; 
               ELSE
                       qry_str := qry_str||' like '||SEARCH_STR; 
               END IF;
                       --dbms_output.put_line( qry_str );
                EXECUTE IMMEDIATE  qry_str  INTO match_count;
                IF match_count > 0 THEN          
                   dbms_output.put_line( qry_str );
                  --dbms_output.put_line( TAB_COL_REC.TABLE_NAME ||' '||TAB_COL_REC.COLUMN_NAME ||' '||match_count);     
                    TAB_COL_RECS := TAB_COL_RECS||'@@'||TAB_COL_REC.TABLE_NAME||'##'||TAB_COL_REC.COLUMN_NAME;
                END IF; 
          END LOOP;
     END SEARCH_DB;    

Anweisung ausführen

  DECLARE
    SEARCH_STR VARCHAR2(200);
    TAB_COL_RECS VARCHAR2(200);
    BEGIN
      SEARCH_STR := 10;
      SEARCH_DB(
        SEARCH_STR => SEARCH_STR,
        TAB_COL_RECS => TAB_COL_RECS
      );
     DBMS_OUTPUT.PUT_LINE('TAB_COL_RECS = ' || TAB_COL_RECS);
     END;

Probenergebnisse

Connecting to the database test.
SELECT COUNT(*) FROM SCOTT.EMP WHERE DEPTNO=10
SELECT COUNT(*) FROM SCOTT.DEPT WHERE DEPTNO=10
TAB_COL_RECS = @@EMP##DEPTNO@@DEPT##DEPTNO
Process exited.
Disconnecting from the database test.

1

Ich habe keine einfache Lösung für den SQL-Promprt. Es gibt jedoch einige Tools wie toad und PL / SQL Developer, die über eine GUI verfügen, über die ein Benutzer die zu durchsuchende Zeichenfolge eingeben kann und die Tabelle / Prozedur / das Objekt zurückgibt, in der bzw. der diese gefunden wird.


1

Es gibt einige kostenlose Tools, mit denen diese Art der Suche durchgeführt werden kann. Diese funktioniert beispielsweise einwandfrei und der Quellcode ist verfügbar: https://sites.google.com/site/freejansoft/dbsearch

Sie benötigen den Oracle ODBC-Treiber und einen DSN, um dieses Tool verwenden zu können.


1

Ändern des Codes, um mithilfe einer LIKE-Abfrage die Groß- und Kleinschreibung nicht zu berücksichtigen, anstatt genaue Übereinstimmungen zu finden ...

DECLARE
  match_count INTEGER;
  -- Type the owner of the tables you want to search.
  v_owner VARCHAR2(255) :='USER';
  -- Type the data type you're looking for (in CAPS). Examples include: VARCHAR2, NUMBER, etc.
  v_data_type VARCHAR2(255) :='VARCHAR2';
  -- Type the string you are looking for.
  v_search_string VARCHAR2(4000) :='Test';
BEGIN
  dbms_output.put_line( 'Starting the search...' );
  FOR t IN (SELECT table_name, column_name FROM all_tab_cols where owner=v_owner and data_type = v_data_type) LOOP
    EXECUTE IMMEDIATE 
    'SELECT COUNT(*) FROM '||t.table_name||' WHERE LOWER('||t.column_name||') LIKE :1'
    INTO match_count
    USING LOWER('%'||v_search_string||'%');
    IF match_count > 0 THEN
      dbms_output.put_line( t.table_name ||' '||t.column_name||' '||match_count );
    END IF;
  END LOOP;
END;

0

- Es wurde ausgeführt - kein Fehler

    SET SERVEROUTPUT ON SIZE 100000

DECLARE
   v_match_count     INTEGER;
   v_counter         INTEGER;




v_owner           VARCHAR2 (255) := 'VASOA';
v_search_string   VARCHAR2 (4000) := '99999';
v_data_type       VARCHAR2 (255) := 'CHAR';
v_sql             CLOB := '';

BEGIN
   FOR cur_tables
      IN (  SELECT owner, table_name
              FROM all_tables
             WHERE     owner = v_owner
                   AND table_name IN (SELECT table_name
                                        FROM all_tab_columns
                                       WHERE     owner = all_tables.owner
                                             AND data_type LIKE
                                                       '%'
                                                    || UPPER (v_data_type)
                                                    || '%')
          ORDER BY table_name)
   LOOP
      v_counter := 0;
      v_sql := '';

      FOR cur_columns
         IN (SELECT column_name, table_name
               FROM all_tab_columns
              WHERE     owner = v_owner
                    AND table_name = cur_tables.table_name
                    AND data_type LIKE '%' || UPPER (v_data_type) || '%')
      LOOP
         IF v_counter > 0
         THEN
            v_sql := v_sql || ' or ';
         END IF;

         IF cur_columns.column_name is not null
         THEN
            v_sql :=
                  v_sql
               || 'upper('
               || cur_columns.column_name
               || ') ='''
               || UPPER (v_search_string)||'''';

            v_counter := v_counter + 1;
         END IF;

      END LOOP;

      IF v_sql is  null
      THEN
         v_sql :=
               'select count(*) from '
            || v_owner
            || '.'
            || cur_tables.table_name;

      END IF;

      IF v_sql is not null
      THEN
         v_sql :=
               'select count(*) from '
            || v_owner
            || '.'
            || cur_tables.table_name
            || ' where '
            || v_sql;
      END IF;

      --v_sql := 'select count(*) from ' ||v_owner||'.'|| cur_tables.table_name ||' where '||  v_sql;


      --dbms_output.put_line(v_sql);
      --DBMS_OUTPUT.put_line (v_sql);

      EXECUTE IMMEDIATE v_sql INTO v_match_count;

      IF v_match_count > 0
      THEN
        DBMS_OUTPUT.put_line (v_sql);
        dbms_output.put_line('Match in ' || cur_tables.owner || ': ' || cur_tables.table_name || ' - ' || v_match_count || ' records');
      END IF;

   END LOOP;
EXCEPTION
   WHEN OTHERS
   THEN
      DBMS_OUTPUT.put_line (
            'Error when executing the following: '
         || DBMS_LOB.SUBSTR (v_sql, 32600));
END;
/

0

Das Ausleihen, leichte Verbessern und Vereinfachen von diesem Blog-Beitrag scheint die folgende einfache SQL-Anweisung recht gut zu machen:

SELECT DISTINCT (:val) "Search Value", TABLE_NAME "Table", COLUMN_NAME "Column"
FROM cols,
     TABLE (XMLSEQUENCE (DBMS_XMLGEN.GETXMLTYPE(
       'SELECT "' || COLUMN_NAME || '" FROM "' || TABLE_NAME || '" WHERE UPPER("'
       || COLUMN_NAME || '") LIKE UPPER(''%' || :val || '%'')' ).EXTRACT ('ROWSET/ROW/*')))
ORDER BY "Table";

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.