PLSQL:将数据从一个表中插入可能的环境到另一个表,同时保持 from_table 名称动态

Posted

技术标签:

【中文标题】PLSQL:将数据从一个表中插入可能的环境到另一个表,同时保持 from_table 名称动态【英文标题】:PLSQL: Insert data form one table in may envs to another table while keeping the from_table name dynamic 【发布时间】:2017-02-14 21:10:22 【问题描述】:

需要将不同环境中存在的表中的数据插入到表中。 env 列表是从 my_env 表中获取的。就我而言,环境的数量可能会有所不同,因此环境名称将是动态的,因此我写如下:

DECLARE
WRK_STS VARCHAR2(2)    := 'PP';
MY_ENV VARCHAR2(50)   := '';
WRK_ENV NUMBER(6)      := 0;
BEGIN
  FOR t in (SELECT DISTINCT(envid) FROM MY_ENV ORDER BY       ENVID ASC)
  LOOP
  WRK_ENV := WRK_ENV+1;
  MY_ENV := 'ENV_' || t.envid || '.table002'; 
  INSERT INTO MYTAB101(DATE,STS, MYENV, nAME, DESCR, MYTYPE)
  SELECT null, ' || WRK_STS|| ',' || WRK_ENV || ',NAME, DESCR,MYTYPE from ' || MY_ENV;
  END LOOP;
EXCEPTION 
 /*Handle exception*/
END;
/
COMMIT;

但我收到错误:

ORA-06550:第 15 行,第 61 列:PL/SQL:ORA-00942:表或视图不存在 ORA-06550:第 12 行,第 3 列:PL/SQL:忽略 SQL 语句 06550。00000 -“行%s,列 %s:\n%s" *原因:通常是 PL/SQL 编译错误。 *行动:承诺。

如果我直接输入环境名称,它的工作方式类似于“来自 ENV368.table002”

有人可以建议这里有什么问题吗?

谢谢!!!

【问题讨论】:

你不能那样做。需要使用 EXECUTE IMMEDIATE 我试过立即执行:EXECUTE IMMEDIATE 'INSERT INTO MYTAB101(DATE,STS, MYENV, name, DESCR, MYTYPE) SELECT null,' || WRK_STS|| ',' || WRK_ENV || ',NAME,DESCR,MYTYPE 来自 '|| MY_ENV;但这也给出了错误 那么错误是什么?? 【参考方案1】:

未经测试,但我希望一般格式是这样的:

declare
    l_wrk_stats varchar2(2) := 'PP';
    l_my_env    varchar2(50);
    l_wrk_env   number(6) := 0;
    l_sql       varchar2(500);
begin
    for r in (
        select distinct envid
        from   my_env
        order by envid
    )
    loop
        l_wrk_env := l_wrk_env + 1;
        l_my_env  := 'ENV_' || r.envid || '.table002';
        l_sql :=
            'insert into mytab101 (date, sts, myenv, name, descr, mytype)' || chr(10) ||
            'select null, :b1, :b2, name, descr, mytype from ' || l_my_env;

        execute immediate l_sql using l_wrk_stats, l_wrk_env;
    end loop;

exception
    when others then
        raise_application_error(-20000, 'Command failed: ' || l_sql, true); 
end;

【讨论】:

我可以将此查询用于 2 个表连接吗?假设我有 table002 和 table001,那么它是否会修改为:'insert into mytab101 (date, sts, myenv, name, descr, mytype)' || chr(10) || '从'中选择空值,:b1,:b2,a.name,a.descr,b.mytype' || l_my_env a, l_my_env2 b || '其中 a.name = b.name';以上一项可以吗?【参考方案2】:

因为'ENV_'字符串中也有下划线,请看下面:

MY_ENV := 'ENV_' || t.envid || '.table002'; 

我认为你的情况应该是:

MY_ENV := 'ENV' || t.envid || '.table002'; 

【讨论】:

【参考方案3】:

这里的主要思想是使用 Dynamic SQL 和 EXECUTE Immediate 来满足您的要求。我已经纠正了你的障碍。我没有测试它,因为我没有工作空间。希望对您有所帮助。

DECLARE
  WRK_STS VARCHAR2(2)  := 'PP';
  MY_ENV  VARCHAR2(50) := '';
  WRK_ENV NUMBER(6)    := 0;
TYPE ENV
IS
  TABLE OF VARCHAR2(100);
  env_tab env;
BEGIN
  EXECUTE IMMEDIATE 'SELECT DISTINCT(envid) FROM '||MY_ENV||'  ORDER BY ENVID' BULK COLLECT INTO env_tab;
  FOR i IN env_tab.FIRST..env_tab.LAST
  LOOP
    WRK_ENV := WRK_ENV+1;
    MY_ENV  := 'ENV_' || ENV_TAB(I) || '.table002';
    EXECUTE IMMEDIATE ' INSERT INTO MYTAB101      
     (date,STS, MYENV, nAME, DESCR, MYTYPE      
      )    
        SELECT NULL,      
        WRK_STS,      
        wrk_env,      
       ''NAME'',      
       ''DESCR'',      
       ''MYTYPE''    
FROM ' || MY_ENV;
  END LOOP;
  COMMIT;
EXCEPTION
WHEN OTHERS THEN
  NULL; --when others should not be used
END;
/

【讨论】:

以上是关于PLSQL:将数据从一个表中插入可能的环境到另一个表,同时保持 from_table 名称动态的主要内容,如果未能解决你的问题,请参考以下文章

MYSQL将数据从一个表插入到另一个表中

如何通过mysql或python将数据插入到另一个具有相同id的表中

如何使用'$row'将一个数据库表中的特定值插入到另一个数据库表中?

ORACLE中用PLSQL如何把一个表中数据通过.DMP文件导出,再导入到另一个数据库的一个相同表结构的表中?

SQL语句 怎么把从一个表中查出来数据插入到另一个表中

从一个数据库表插入到另一个