PLSQL:将数据从一个 table 插入到另一个 table 中,同时保持 from_table 名称动态

PLSQL: Insert data form one table in may envs to another table while keeping the from_table name dynamic

需要将数据从存在于不同环境中的 table 插入到 table。 env 列表是从 my_env table 获得的。对于我的情况,envs 的数量可能会有所不同,因此 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:table 或视图不存在 ORA-06550:第 12 行,第 3 列:PL/SQL : SQL Statement ignored 06550. 00000 - "line %s, column %s:\n%s" *原因:通常是 PL/SQL 编译错误。 *行动:承诺。

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

有人可以指出这里有什么问题吗?

谢谢!!!

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

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

我认为你的情况应该是:

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

这里的主要思想是使用 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;
/

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

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;