2

这个问题是关于不允许“创建”权限的环境。版本是:Oracle 数据库 10g 和 PL/SQL 8.0.0.1480

下面是一个小示例,展示了我要完成的工作,即循环遍历集合中的一组“字段”并用一些值填充它们。每个“字段”都具有相同的根名称“MyCol_”,后跟一个数字。

例如:MyCol_1、MyCol_2、...、MyCol_n。

我能够建立我的串联,但我无法让EXECUTE IMMEDIATE工作。

我可以在“MyCol_1”是硬编码值的地方运行这些行:

MyCol_1.EXTEND;        
MyCol_1(1) := 'abc';

但是当我用连接的字符串替换那些硬编码的值时,它会失败

v_LoopCounter:=1;        
v_MyTestCode := 'MyCol_' || v_LoopCounter || '.EXTEND' ;
DBMS_OUTPUT.PUT_LINE('Present value of v_MyTestCode: '||v_MyTestCode);
execute immediate v_MyTestCode;     -- <<<-- ERRORS ON THIS LINE <<<--

出现的错误是:ORA-00900:无效的 SQL 语句

我试图遵循这个网站给出的建议:http: //docs.oracle.com/cd/B10501_01/appdev.920/a97269/pc_13dyn.htm

...将动态 SQL 语句存储在字符串中,该字符串必须是主变量或带引号的文字。将 SQL 语句存储在字符串中时,省略关键字 EXEC SQL 和 ';' 语句终止符。

还有来自: http ://www.databasejournal.com/features/oracle/article.php/2109681/EXECUTE-IMMEDIATE-option-for-Dynamic-SQL-and-PLSQL.htm 的建议

我已经尝试了许多关于 EXECUTE IMMEDIATE 的变体,例如 EXEC、EXECUTE,但没有任何成功。

这是完整的代码示例。这只是一些尝试调试此问题的 beta 代码。我希望这不会分散关于使用连接字符串的 EXECUTE IMMEDIATE 的问题。我试图保持示例代码简单且有据可查。希望这有助于解释这种情况。

DECLARE

   TYPE MyNestedTable IS TABLE of varchar2(100);       

   MyCol_1 MyNestedTable;
   MyCol_2 MyNestedTable;

   v_LoopCounter  NUMBER;

   v_MyTestCode   VARCHAR2(200);
   v_SomeValue    VARCHAR2(200);

BEGIN

    MyCol_1 := MyNestedTable();
    MyCol_2 := MyNestedTable(); 

    v_LoopCounter:=1;

    v_MyTestCode := 'MyCol_' || v_LoopCounter || '.EXTEND' ;
    DBMS_OUTPUT.PUT_LINE('Present value of v_MyTestCode: '||v_MyTestCode);
    EXECUTE IMMEDIATE v_MyTestCode;     -- <<<-- ERRORS ON THIS LINE <<<--

    v_SomeValue := 'abc';
    v_MyTestCode := 'MyCol_' || v_LoopCounter || ':= '||v_SomeValue;
    DBMS_OUTPUT.PUT_LINE('Present value of v_MyTestCode: '||v_MyTestCode);
    EXECUTE IMMEDIATE v_MyTestCode;     -- <<<-- ERRORS ON THIS LINE <<<--


        MyCol_2.EXTEND;
        MyCol_2(1) := 200;
        DBMS_OUTPUT.PUT_LINE('MyCol_2 '||MyCol_2(1));    
        DBMS_OUTPUT.PUT_LINE('MyCol_1 '|| ', '||'MyCol_2 ');            DBMS_OUTPUT.PUT_LINE(MyCol_1(1)|| ', '||MyCol_2(1));

END;
4

1 回答 1

3

Collection.EXTEND它不是一个SQL完整的语句,它是一个用于扩展集合的 PLSQL 语句。话虽如此,下面的代码将永远无法工作-

v_LoopCounter:=1;        
v_MyTestCode := 'MyCol_' || v_LoopCounter || '.EXTEND' ;
execute immediate v_MyTestCode;

但是,如果动态 sql 是一个完整的 PLSQL 存根/匿名块,EXECUTE IMMEDIATE则将对其进行处理。喜欢

v_LoopCounter:=1;        
v_MyTestCode := 'begin MyCol_' || v_LoopCounter || '.EXTEND;end;' ;
execute immediate v_MyTestCode;

这可能达到目的,但如果上述是从存储过程本身内完成的,那么范围.EXTEND是有问题的(即未经测试)。您可以尝试看看它是否有效。

于 2012-09-15T03:39:58.597 回答