如何从它所在的所有表中选择一列?

时间:2014-07-14 14:36:52

标签: sql oracle

我有很多表具有相同的列'customer_number'。 我可以通过查询得到所有这些表的列表:

SELECT table_name FROM ALL_TAB_COLUMNS 
WHERE COLUMN_NAME = 'customer_number';

问题是如何从所有这些表中获取具有特定客户编号的所有记录,而不对每个表运行相同的查询。

3 个答案:

答案 0 :(得分:2)

要从表中获取记录,您已针对该表编写查询。因此,您无法从具有指定字段的表中获取所有记录,而无需对每个表进行查询。

如果您感兴趣的列的子集和所有表之间共享此子集,您可以使用UNION / UNION ALL操作,如下所示:

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'

或者,在简单的情况下,您只想知道哪些表有关于特定客户的记录

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'

否则你必须单独查询每个表。

答案 1 :(得分:2)

DBMS_XMLGEN使您无需自定义PL / SQL即可运行动态SQL语句。

示例架构

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

<强>查询

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

<强>警告

这些过于通用的解决方案通常存在问题。它们不像普通的旧SQL语句那样表现不佳,而且更容易遇到错误。通常,生产代码应避免使用这些类型的解决方案。但它们对于即席查询仍然非常有用。

此外,此解决方案假定您希望每行都有相同的列。如果每一行都不同,那么事情会变得复杂得多,你可能需要研究像ANYDATASET这样的技术。

答案 2 :(得分:1)

我假设你想自动化这个。两种方法。

  1. 用于生成SQL脚本的SQL
  2. 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
    2. 使用动态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;