s.t.nguyen
s.t.nguyen

Reputation: 74

How to select a column from all tables in which it resides?

I have many tables that have the same column 'customer_number'. I can get a list of all these table by query:

SELECT table_name FROM ALL_TAB_COLUMNS 
WHERE COLUMN_NAME = 'customer_number';

The question is how do I get all the records that have a specific customer number from all these tables without running the same query against each of them.

Upvotes: 2

Views: 850

Answers (3)

Jon Heller
Jon Heller

Reputation: 36807

DBMS_XMLGEN enables you to run dynamic SQL statements without custom PL/SQL.

Sample Schema

create table table1(customer_number number, a number, b number);
insert into table1 values(1,1,1);
create table table2(customer_number number, a number, c number);
insert into table2 values(2,2,2);
create table table3(a number, b number, c number);
insert into table3 values(3,3,3);

Query

--Get CUSTOMER_NUMBER and A from all tables with the column CUSTOMER_NUMBER.
--
--Convert XML to columns.
select
    table_name,
    to_number(extractvalue(xml, '/ROWSET/ROW/CUSTOMER_NUMBER')) customer_number,
    to_number(extractvalue(xml, '/ROWSET/ROW/A')) a
from
(
    --Get results as XML.
    select table_name,
        xmltype(dbms_xmlgen.getxml(
            'select customer_number, a from '||table_name
        )) xml
    from user_tab_columns
    where column_name = 'CUSTOMER_NUMBER'
);


TABLE_NAME  CUSTOMER_NUMBER  A
----------  ---------------  -
TABLE1      1                1
TABLE2      2                2

Warnings

These overly generic solutions often have issues. They won't perform as well as a plain old SQL statements and they are more likely to run into bugs. In general, these types of solutions should be avoided for production code. But they are still very useful for ad hoc queries.

Also, this solution assumes that you want the same columns from each row. If each row is different then things get much more complicated and you may need to look into technologies like ANYDATASET.

Upvotes: 2

TenG
TenG

Reputation: 4004

I assume you want to automate this. Two approaches.

  1. SQL to generate SQL scripts

.

spool run_rep.sql 
set head off pages 0 lines 200 trimspool on feedback off

SELECT 'prompt ' || table_name || chr(10) || 

       'select ''' || table_name ||
         ''' tname, CUSTOMER_NUMBER from ' || table_name || ';' cmd
FROM all_tab_columns
WHERE column_name = 'CUSTOMER_NUMBER';

spool off

@ run_rep.sql
  1. PLSQL

Similar idea to use dynamic sql:

DECLARE
   TYPE rcType IS REF CURSOR;
   rc   rcType;
   CURSOR c1 IS SELECT table_name FROM all_table_columns WHERE column_name = 'CUST_NUM';
   cmd   VARCHAR2(4000);
   cNum  NUMBER;
BEGIN
   FOR r1 IN c1 LOOP
      cmd := 'SELECT cust_num FROM ' || r1.table_name ;
      OPEN rc FOR cmd;
      LOOP
         FETCH rc INTO cNum;
         EXIT WHEN rc%NOTFOUND;
         -- Prob best to INSERT this into a temp table and then
         -- select * that to avoind DBMS_OUTPUT buffer full issues
         DBMS_OUTPUT.PUT_LINE ( 'T:' || r1.table_name || ' C: ' || rc.cust_num );
      END LOOP;
      CLOSE rc;
   END LOOP;
END;

Upvotes: 1

vav
vav

Reputation: 4684

To get record from a table, you have write a query against that table. So, you can't get ALL the records from tables with specified field without a query against each one of these tables.

If there is a subset of columns that you are interested in and this subset is shared among all tables, you may use UNION/UNION ALL operation like this:

select * from (
select customer_number, phone, address from table1
union all
select customer_number, phone, address from table2
union all
select customer_number, phone, address from table3
)
where customer_number = 'my number'

Or, in simple case where you just want to know what tables have records about particular client

select * from (
select 'table1' src_tbl, customer_number from table1
union all
select 'table2', customer_number from table2
union all
select 'table3', customer_number from table3
)
where customer_number = 'my number'

Otherwise you have to query each table separatelly.

Upvotes: 2

Related Questions