使用特定数据从许多表创建表

时间:2013-10-08 12:45:37

标签: sql oracle stored-procedures plsql

我们有oracle11g。

我需要编写存储过程(或者可能是创建视图的另一种解决方案),它将执行旧表并插入新的更新数据。

我们在数据库中有许多表,名称为%table_name%+ number_prefix。

例如:Country_1Country_2

以下是此表中的数据:

id     code     country
103858 834      TZ
103878 834      UA
103859 800      UG
103860 894      ZM
103861 716      ZW        
103862 24       AO

我们还有表Country_all,其中包含所有这些表格中的特定信息。

如果用户从web gui new Country_%prefix%表添加新表,我必须更新Country_all表。此表应按代码分组,并将所有国家/地区放在一行(TZ,UA,UG ...):

table    code    countries
91    2005202000    ,AD,AL,AQ,AS,AT,
91    2005400000    ,AD,AL,AQ,AS,AT,
91    2005995000    ,AD,AL,AQ,AS,AT,
91    2005997000    ,AD,AL,AQ,AS,AT,
91    2006003100    ,AD,AL,AQ,AS,AT,

此处91表示表Country_91

中的此数据

我用它从表中获取前缀:

EXECUTE IMMEDIATE 'truncate table COUNTRY_ALL';
FOR r IN (SELECT regexp_replace(table_name,'(.*)_', '\1') ADD_NUM
FROM all_tables
WHERE upper(table_name)
LIKE ('COUNTRY_%'))

但是当我尝试使用r.ADD_NUM时,我遇到了麻烦。

INSERT INTO COUNTRY_ALL
SELECT r.ADD_NUM, code, listagg(code, ',') WITHIN GROUP (ORDER BY code) AS GI_COUNTRIES
FROM 'COUNTRY_' || r.ADD_NUM
GROUP BY code;

我也尝试声明一些变量并将COUNTRY_ || r.ADD_NUM赋给变量,但它也不想从变量中查询。

更新

最后我昨天做了!

我是以两种方式做到的。 第一个正是我所要求的:

BEGIN
  EXECUTE IMMEDIATE 'truncate table Countries_ALL';
  FOR r IN (SELECT regexp_replace(table_name,'_(.*)', '\1') ADD_NUM
        FROM all_tables
        WHERE upper(table_name)
        LIKE ('COUNTRY_%')
        AND owner='owner_name')
  loop


    EXECUTE IMMEDIATE  'INSERT COUNTRIES_ALL
      SELECT '|| r.ADD_NUM ||' as ADD_NUM, code, listagg(countries, '','') WITHIN GROUP (ORDER BY countries) AS COUNTRIES
      FROM COUNTRY_' || r.ADD_NUM || '
      GROUP by code;         
  END loop;
END;

第二一个更好。我创建了2个临时表:CURRENTFOR_UPDATING

填写CURRENT

INSERT INTO CURRENT
SELECT DISTINCT ADD_NUM FROM COUNTRIES_ALL;

与上一个不同,只更新现有表格的程序:

DECLARE
BEGIN
execute IMMEDIATE 'TRUNCATE table for_updating';

  INSERT INTO for_updating
    SELECT regexp_replace(table_name,'_(.*)', '\5 ') as ADD_NUM
        FROM all_tables
         WHERE owner='owner_name'
         AND table_name LIKE 'COUNTRY_%';

for num in (
SELECT b.add_num FROM CURRENT A
RIGHT JOIN for_updating b
ON A.add_num=b.add_num
WHERE A.add_num IS NULL) 
loop
    EXECUTE IMMEDIATE  'INSERT INTO COUNTRIES_ALL
          SELECT '||num.add_num||' as ADD_NUM, code, listagg(countries, '','') WITHIN GROUP (ORDER BY countries) AS GI_COUNTRIES
          FROM COUNTRY_' || num.ADD_NUM || '
          GROUP by code';

end loop;

END;

在这个程序中,我比较了COUNTRIES_ALL中已有的表和all_tables中的表。然后将插入所有新表。

感谢Przemyslaw Kruglej的耐心等待!

1 个答案:

答案 0 :(得分:0)

您无法使用表的动态名称运行查询。

您必须为每个表生成查询,使用dbms_sql包或EXECUTE IMMEDIATE。

你知道你应该工作的桌子的数量吗?如果是这样,您可以使用EXECUTE IMMEDIATE:

EXECUTE IMMEDIATE
  'INSERT INTO COUNTRY_ALL
    SELECT r.ADD_NUM, code, listagg(code, '','') WITHIN GROUP (ORDER BY code) AS GI_COUNTRIES
      FROM COUNTRY_' || tab_number ||
    ' GROUP BY code';