我必须创建一个库存过程来创建一个表,用于记录树的类型和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;
后面跟着类似的插入和变量增量,但是当我执行这个时,我得到了表不存在的插入错误,这只能表示没有创建表。在此先感谢您的任何帮助
答案 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)。