domingo, 7 de diciembre de 2014

Buscar una tabla por el valor en una de sus columnas

Puede darse el caso que deseemos encontrar el nombre de una tabla de la cual solo sabemos un valor específico para un registro y columna. Esta búsqueda puede ser muy pesada para la base de datos si existen muchas tablas o registros en ella, así que debemos intentar indicar el mayor número de condiciones posibles.

En el siguiente trozo de PL/SQL seleccionamos en una primera consulta todas las tablas y columnas donde podría encontrarse el literal que buscamos. Filtramos por el esquema al que estamos conectados (USER) o el que deseemos, tipo de dato de la columna o una longitud mínima, calculada con el literal de mayor longitud que hemos podido encontrar. Sin embargo para el literal a comparar recomendamos que sea lo más corto posible a fin de aligerar la operación de comparación.

Posteriormente en un bucle, para cada columna y tabla encontrada, se realiza una búsqueda para encontrar un registro que cumpla con nuestro literal.
set serveroutput on;

DECLARE
  match_count integer;
  v_search_string varchar2(100) := 'Civilization... solo un turno más';
BEGIN  
  FOR t IN (SELECT owner, table_name, column_name 
              FROM all_tab_columns 
              WHERE owner = USER and DATA_TYPE = 'VARCHAR2' and DATA_LENGTH >= 37
            ) LOOP   
    EXECUTE IMMEDIATE    
      'SELECT COUNT(*) FROM '||t.owner || '.' || 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.owner || '.' || t.table_name ||' '||t.column_name||' '||match_count );
    END IF; 
    
  END LOOP;
  
  dbms_output.put_line('Fin');
END;
/