Sql 从包含特定数据的多个表中创建表

Sql 从包含特定数据的多个表中创建表,sql,oracle,stored-procedures,plsql,Sql,Oracle,Stored Procedures,Plsql,我们有oracle11g 我需要编写存储过程,或者可能是另一种解决方案,如创建视图,它将truncute旧表并插入新的更新数据 数据库中有许多表的名称为%table\u name%+number\u前缀 例如:国家1,国家2 以下是这些表中的数据: id code country 103858 834 TZ 103878 834 UA 103859 800 UG 103860 894 ZM 103861 716 ZW

我们有oracle11g

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

数据库中有许多表的名称为%table\u name%+number\u前缀

例如:国家1,国家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新国家/地区\前缀%表格添加新表格,我必须更新国家/地区\所有表格。此表应按代码分组,并将所有国家/地区放在一行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;
第二个更好。我创建了两个临时表:CURRENT和FOR_update

要填充电流:

和只更新现有表的过程不同,上一个过程是:

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\u ALL中已有的表和我在ALL\u表中已有的表。然后将插入所有新表


感谢Przemyslaw Kruglej的耐心

不能使用表的动态名称运行查询

您必须为每个表生成查询、使用dbms_sql包或立即执行

你知道你要处理的桌子的号码吗?如果是,您可以使用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';

谢谢实际上我知道新桌子的号码。但是我希望这个东西是自动的。好吧,但是如果你能够以某种方式动态地获得你必须使用的表的数量,你可以使用我在我的帖子中写的东西。还是我遗漏了什么?现在是什么阻止您自动执行此操作?例如,用户添加一些新表。现在,我应该使用获得的数字手动运行该过程。但我需要每天自动运行的程序。如果我选择distinct add_num from country_all并获得我已经拥有的数字,会怎么样。然后使用previuos代码获取所有数字。我如何比较它们以得到唯一新的?可以只使用pl/sql?所以您想知道今天创建了哪些表-您可以将前一天创建的最后一个表的编号存储在一些配置表中,然后运行作业,该作业将获得新的数值,新的数值等于大于记忆值的数值,并对这些表执行立即执行。然后,完成后,将最后一个表的编号更新为与您在当天作业中更新的最后一个表的编号相同。您还可以检查正在使用的表的DDL时间,但我不建议使用这种方法第一种方法更好。在添加数字之前-这有帮助吗?不,没有。我认为问题出在listaggcode中,您是否可以在不使用EXECUTE IMMEDIATE的情况下作为独立查询运行此查询?那么它能工作吗?是的,它能工作,没有立即执行,它说匿名块完成了,而且我必须删除一对单引号,>',啊。。删除结束撇号前的分号,如下所示:执行立即“插入国家/地区”全部选择r.ADD_NUM,code,listaggcode,按代码分组,作为GI_国家/地区的GI|tab|u编号|按代码分组”;
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';