【问题标题】:Using variables in oracle as table names for insert command oracle使用 oracle 中的变量作为插入命令 oracle 的表名
【发布时间】:2019-04-04 20:28:04
【问题描述】:

尝试创建一个过程,该过程将插入或更新某个表,该表的名称存储在具有更多信息的另一个表中。

CREATE OR REPLACE PROCEDURE LIMPAR_TAB_proc IS

--stmt VARCHAR2(1000);
n_tab sii_bck_cfg_tab.nome_tab%type;
prefix sii_bck_cfg_tab.pref_tab_bck%type;
max_reg sii_bck_cfg_tab.max_reg_bck%type;
id_fk sii_bck_cfg_tab.id_bck_cfg_tab%type;
n_tab2 sii_bck_tab.nome_tab%type;
testes VARCHAR2(500);

CURSOR c1 IS
SELECT ID_BCK_CFG_TAB,Nome_tab, pref_tab_bck, max_reg_bck FROM 
sii_bck_cfg_tab WHERE desativado_em IS NULL OR desativado_em<=SYSDATE AND 
n_dias_reten>0 ORDER BY criado_em; 

CURSOR c2 IS 
SELECT sii_bck_tab.ID_BCK_CFG_TAB , sii_bck_tab.nome_tab from 
sii_bck_tab,sii_bck_cfg_tab WHERE 
sii_bck_cfg_tab.id_bck_cfg_tab=sii_bck_tab.id_bck_cfg_tab and dt_fecho is 
NULL ;

BEGIN                                  

OPEN c1;

LOOP
FETCH c1 INTO id_fk,n_tab,prefix,max_reg;
EXIT WHEN c1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('Nome Tabela = ' || id_fk ||' '|| n_tab ||' '|| prefix 
||' '|| max_reg); 
    OPEN c2;
      LOOP 
         FETCH c2 INTO id_fk, n_tab2;
         EXIT WHEN c2%NOTFOUND;
         DBMS_OUTPUT.PUT_LINE('chave aqui = ' || id_fk || n_tab2);
         IF c2%FOUND THEN

         testes:= 'INSERT INTO ' || n_tab2 || 'select * from ' || n_tab;
         EXECUTE IMMEDIATE testes;
         END IF;  
      END LOOP;
      CLOSE c2;

END LOOP;
CLOSE c1;

所以我将尝试解释我的最终目标,我想通过我的 cursor1,当我找到一个通过验证的表时,我进入我的 cursor2。在我的第二个循环中,我将要验证是否有一个表与我的 cursor1 上的表关联(未实现),然后如果我找到一个未关联的表,我将需要创建一个与原始字段相同的表(其中这就是为什么我试图将表名保存在变量中)。如果它存在并且它的 dt_fim(date end) 为空,那么我需要将来自 cursor1 (n_tab) 的表中的所有数据插入到 cursor2(n_tab2) 上找到的表中。

我将尝试进一步解释任何疑问,我仍然感到困惑,才刚刚开始。

感谢您的任何建议/帮助。

【问题讨论】:

    标签: sql oracle select procedure


    【解决方案1】:

    这是正确的语法,但不推荐用于如此简单的操作

    testes:= 'INSERT INTO ' || n_tab2 ||' SELECT * FROM ' || n_tab;
    EXECUTE IMMEDIATE testes;
    

    因为在插入中显式指定列名更可取(并且更安全),如果要动态执行,则需要额外的块。

    INSERT INTO tab2(col1,col2,col3)  SELECT col1,col2,col3 FROM tab;
    

    顺便说一句,您为什么将表名放在变量中而不是直接插入?

    【讨论】:

    • 声明中需要VALUES吗?我使用循环来获取我需要的名称,所以我真的不知道任何其他方式来执行此过程,这就是我尝试使用变量的原因。
    • @Sapo121 :编辑您的问题并向我们展示您要完成的工作的全貌。
    • 我试图解释我的最终目标是什么,但我还差得很远,所以我没有把所有的信息都放进去
    • 我不知道我需要插入哪个表,所以我不知道它会有多少列或哪些列
    • @Sapo121 :好吧,看起来您的源表和目标表名称来自另一个表的列,动态插入似乎是不可避免的,尽管我认为这是一个糟糕的设计。您可以继续使用我给您的选项 1,它会起作用,除非源表和目标表之间存在 列顺序 不匹配,在这种情况下,您必须在最终查询中动态引入列。此外,更喜欢隐式游标循环而不是 open..fetch 循环。
    【解决方案2】:

    试试下面这个块来传递表名作为变量:

    declare
    table_1 varchar2(10):='N_tab';
    table_2 varchar2(10):='N_tab2';
    test varchar2(1000);
    begin
    
    test:= 'INSERT all into ' || table_2 || ' SELECT * FROM ' ||table_1;
    EXECUTE IMMEDIATE test;
    dbms_output.put_line (test);
    
    end;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-24
      • 2014-08-15
      • 2010-11-13
      • 1970-01-01
      • 1970-01-01
      • 2015-09-06
      • 1970-01-01
      • 2015-02-16
      相关资源
      最近更新 更多