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

前端 未结 3 1714
北海茫月
北海茫月 2021-01-07 01:58

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         


        
相关标签:
3条回答
  • 2021-01-07 02:10

    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.

    0 讨论(0)
  • 2021-01-07 02:14

    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;
    
    0 讨论(0)
  • 2021-01-07 02:15

    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.

    0 讨论(0)
提交回复
热议问题