表创建的EXECUTE IMMEDIATE语句不起作用

时间:2015-03-19 16:31:35

标签: plsql

我必须创建一个库存过程来创建一个表,用于记录树的类型和X和Y坐标。我知道您必须使用EXECUTE IMMEDIATE语句才能创建表格以下代码:

Create or replace Procedure add_populate_trees 
(p_treenum in NUMBER)
IS
v_loop_counter NUMBER := 0;
v_artari_counter NUMBER :=0;
v_mesteceni_counter NUMBER :=0;
v_fagi_counter NUMBER :=0;
v_arini_counter NUMBER :=0;
v_stejari_counter NUMBER :=0;
BEGIN
EXECUTE IMMEDIATE 'drop table copaci';
EXECUTE IMMEDIATE 'create table copaci (Tip_copac VARCHAR2(25), Coord_X NUMBER(5), Coord_Y NUMBER(5))';
WHILE v_loop_counter <= p_treenum LOOP
    INSERT INTO copaci (Tip_copac, Coord_X, Coord_Y) Values('Artar',DBMS_RANDOM.value(0,1000000),DBMS_RANDOM.value(0,1000000));
    v_artari_counter := v_artari_counter + 1;
    v_loop_counter :=v_loop_counter + 1;
INSERT INTO copaci (Tip_copac, Coord_X, Coord_Y) Values('Mesteacan',DBMS_RANDOM.value(0,1000),DBMS_RANDOM.value(0,1000));
    v_mesteceni_counter := v_mesteceni_counter + 1;
    v_loop_counter := v_loop_counter + 1;


    INSERT INTO copaci (Tip_copac, Coord_X, Coord_Y) Values('Fag',DBMS_RANDOM.value(0,1000),DBMS_RANDOM.value(0,1000));
    v_fagi_counter := v_fagi_counter + 1;
    v_loop_counter := v_loop_counter + 1;


    INSERT INTO copaci (Tip_copac, Coord_X, Coord_Y) Values('Arin',DBMS_RANDOM.value(0,1000),DBMS_RANDOM.value(0,1000));
    v_arini_counter := v_arini_counter + 1;
    v_loop_counter := v_loop_counter + 1;


    INSERT INTO copaci (Tip_copac, Coord_X, Coord_Y) Values('Stejar',DBMS_RANDOM.value(0,1000),DBMS_RANDOM.value(0,1000));
    v_stejari_counter := v_stejari_counter + 1;
    v_loop_counter := v_loop_counter + 1;
END LOOP;
DBMS_OUTPUT.PUT_LINE('In padure au fost plantati '||v_artari_counter||'artari');
DBMS_OUTPUT.PUT_LINE('In padure au fost plantati '||v_mesteceni_counter||'mesteceni');
DBMS_OUTPUT.PUT_LINE('In padure au fost plantati '||v_fagi_counter||'fagi');
DBMS_OUTPUT.PUT_LINE('In padure au fost plantati '||v_arini_counter||'arini');
DBMS_OUTPUT.PUT_LINE('In padure au fost plantati '||v_stejari_counter||'stejari');
end;

后面跟着类似的插入和变量增量,但是当我执行这个时,我得到了表不存在的插入错误,这只能表示没有创建表。在此先感谢您的任何帮助

2 个答案:

答案 0 :(得分:1)

如果在最初尝试编译并执行该过程时该表不存在,则会出现错误。这是因为PL / SQL在编译时验证它引用的对象。引用可能存在的表的唯一方法是使用EXECUTE IMMEDIATE。解决此问题的最简单方法是在最初创建过程之前运行create table脚本。

但是,对于Oracle,从过程代码发出DDL通常是一个坏主意。每次使用它时,不是删除和重新创建表,处理此类要求的最佳方法是创建一次global temporary table(GTT)并编写代码以引用它。 GTT的值会在您提交或会话结束时自动退出(取决于您在创建时选择的选项),因此在会话中首次访问时,它始终是干净的。


访问过程中尚未存在的表的唯一方法是将对它的每个引用更改为EXECUTE IMMEDIATE。由于您没有将任何变量传递给insert命令,这应该只是将它们变成字符串。

答案 1 :(得分:0)

&copaci&#39;在调用程序之前存在表?如果没有,一旦你试图发出删除表copaci&#39;命令。包装您的drop语句,看看是否发生了什么,并允许您的程序继续:

BEGIN
  EXECUTE IMMEDIATE 'drop table copaci';
EXCEPTION WHEN OTHERS THEN
  dbms_output.put_line('exception occurred because the copaci table did not exist');
END;   

如果您遇到“权限不足”错误,请查看以下答案: Execute Immediate within a stored procedure keeps giving insufficient priviliges error

如果这是您的问题,则需要添加AUTHID:

Create or replace Procedure add_populate_trees 
(p_treenum in NUMBER)
AUTHID CURRENT_USER
IS
v_loop_counter NUMBER := 0;
v_artari_counter NUMBER :=0;
v_mesteceni_counter NUMBER :=0;
v_fagi_counter NUMBER :=0;
v_arini_counter NUMBER :=0;
v_stejari_counter NUMBER :=0;
BEGIN
  BEGIN
    EXECUTE IMMEDIATE 'drop table copaci';
  EXCEPTION WHEN OTHERS THEN
    NULL;
  END;  
EXECUTE IMMEDIATE 'create table copaci (Tip_copac VARCHAR2(25), Coord_X NUMBER(10), Coord_Y NUMBER(10))';
WHILE v_loop_counter <= p_treenum LOOP
    EXECUTE IMMEDIATE 'INSERT INTO copaci (Tip_copac, Coord_X, Coord_Y) Values(''Artar'',DBMS_RANDOM.value(0,1000000),DBMS_RANDOM.value(0,1000000))';
    v_artari_counter := v_artari_counter + 1;
    v_loop_counter :=v_loop_counter + 1;
    EXECUTE IMMEDIATE 'INSERT INTO copaci (Tip_copac, Coord_X, Coord_Y) Values(''Mesteacan'',DBMS_RANDOM.value(0,1000),DBMS_RANDOM.value(0,1000))';
    v_mesteceni_counter := v_mesteceni_counter + 1;
    v_loop_counter := v_loop_counter + 1;


    EXECUTE IMMEDIATE 'INSERT INTO copaci (Tip_copac, Coord_X, Coord_Y) Values(''Fag'',DBMS_RANDOM.value(0,1000),DBMS_RANDOM.value(0,1000))';
    v_fagi_counter := v_fagi_counter + 1;
    v_loop_counter := v_loop_counter + 1;


    EXECUTE IMMEDIATE 'INSERT INTO copaci (Tip_copac, Coord_X, Coord_Y) Values(''Arin'',DBMS_RANDOM.value(0,1000),DBMS_RANDOM.value(0,1000))';
    v_arini_counter := v_arini_counter + 1;
    v_loop_counter := v_loop_counter + 1;


    EXECUTE IMMEDIATE 'INSERT INTO copaci (Tip_copac, Coord_X, Coord_Y) Values(''Stejar'',DBMS_RANDOM.value(0,1000),DBMS_RANDOM.value(0,1000))';
    v_stejari_counter := v_stejari_counter + 1;
    v_loop_counter := v_loop_counter + 1;
END LOOP;
DBMS_OUTPUT.PUT_LINE('In padure au fost plantati '||v_artari_counter||'artari');
DBMS_OUTPUT.PUT_LINE('In padure au fost plantati '||v_mesteceni_counter||'mesteceni');
DBMS_OUTPUT.PUT_LINE('In padure au fost plantati '||v_fagi_counter||'fagi');
DBMS_OUTPUT.PUT_LINE('In padure au fost plantati '||v_arini_counter||'arini');
DBMS_OUTPUT.PUT_LINE('In padure au fost plantati '||v_stejari_counter||'stejari');
end;

请注意,您尝试插入的值不适合您的列,因此我必须将大小增加到数字(10)。