Saltar al contenido

Buscar todos los campos en todas las tablas para un valor específico (Oracle)

Pudiera darse el caso de que halles algún problema en tu código o trabajo, recuerda probar siempre en un entorno de testing antes subir el código al trabajo final.

Solución:

Cita:

Intenté usar esta declaración a continuación para encontrar una columna adecuada en función de lo que creo que debería llamarse, pero no arrojó resultados. *

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

Una columna no es un objeto. Si quiere decir que espera que el nombre de la columna sea como ‘% DTN%’, la consulta que desea es:

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

Pero si el ‘DTN’ string es solo una suposición de su parte, que probablemente no ayude.

Por cierto, ¿qué tan seguro está de que ‘1/22 ​​/ 2008P09RR8’ es un valor seleccionado directamente de una sola columna? Si no sabe en absoluto de dónde proviene, podría ser una concatenación de varias columnas, o el resultado de alguna función, o un valor que se encuentra en un objeto de tabla anidado. Por lo tanto, es posible que esté en una búsqueda inútil tratando de verificar cada columna para ese valor. ¿No puede comenzar con cualquier aplicación cliente que muestre este valor e intentar averiguar qué consulta está utilizando para obtenerlo?

De todos modos, la respuesta de diciu ofrece un método para generar consultas SQL para verificar el valor de cada columna de cada tabla. También puede hacer cosas similares por completo en una sesión SQL utilizando un bloque PL / SQL y SQL dinámico. Aquí hay un código escrito apresuradamente para eso:

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

Hay algunas formas de hacerlo más eficiente también.

En este caso, dado el valor que estás buscando, claramente puedes eliminar cualquier columna que sea del tipo NUMBER o DATE, lo que reduciría el número de consultas. Tal vez incluso restringirlo a columnas donde el tipo es como ‘% CHAR%’.

En lugar de una consulta por columna, puede crear una consulta por tabla como esta:

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

Hice algunas modificaciones en el código anterior para que funcione más rápido si está buscando en un solo propietario. Solo tiene que cambiar las 3 variables v_owner, v_data_type y v_search_string para que se ajusten a lo que está buscando.

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

Sé que este es un tema antiguo. Pero veo un comentario a la pregunta preguntando si se podría hacer en SQL en lugar de usar PL/SQL. Así que pensé en publicar una solución.

La siguiente demostración es para Busque un VALOR en todas las COLUMNAS de todas las TABLAS en un ESQUEMA completo:

  • Buscar un Tipo de caracter

Busquemos el valor KING en SCOTT esquema.

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>
  • Buscar un Tipo NUMÉRICO

Busquemos el valor 20 en SCOTT esquema.

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>

No se te olvide dar visibilidad a esta noticia si te fue de ayuda.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *