未使用存储过程创建索引-Oracle

未使用存储过程创建索引-Oracle,oracle,plsql,dynamic-sql,Oracle,Plsql,Dynamic Sql,我使用以下存储过程在表上创建索引: CREATE OR REPLACE PROCEDURE create_index ( in_tb VARCHAR2, in_index VARCHAR2, in_columns VARCHAR2, lc_status OUT NUMBER ) AS lc_affected NUMBER; lc_stmt VARCHAR2(1500); BEGIN

我使用以下存储过程在表上创建索引:

CREATE OR REPLACE PROCEDURE create_index (
    in_tb        VARCHAR2,
    in_index     VARCHAR2,
    in_columns   VARCHAR2,
    lc_status    OUT          NUMBER
) AS
    lc_affected   NUMBER;
    lc_stmt       VARCHAR2(1500);
BEGIN
    lc_stmt := 'BEGIN EXECUTE IMMEDIATE ''CREATE INDEX '
               || in_index
               || ' ON '
               || in_tb
               || ' ('
               || in_columns
               || ')''; END;';

    dbms_output.put_line(lc_stmt);
    dbms_utility.exec_ddl_statement(lc_stmt);
    lc_affected := SQL%rowcount;
    dbms_output.put_line('AFFECTED -->' || lc_affected);
    IF ( lc_affected > 0 ) THEN
        lc_status := 1;
    ELSE
        lc_status := 1;
    END IF;

END create_index;
/
我使用以下命令执行存储过程:

SET SERVEROUTPUT ON;
DECLARE
    lc_status   NUMBER;
BEGIN
    create_index('TABLE_1_LOAD', 'ON_RUN_INDEX', 'MY_ID', lc_status);
END;
但是,没有在表1\u LOAD中创建索引

输出为:

BEGIN EXECUTE IMMEDIATE 'CREATE INDEX ON_RUN_INDEX ON TABLE_1_LOAD (MY_ID)'; END;
AFFECTED -->

PL/SQL procedure successfully completed.

我无法理解存储过程为什么不创建索引。您能提供帮助吗?

您试图通过exec_ddl_语句运行的动态语句不是ddl。它包含DDL,但嵌入在匿名PL/SQL块中,这与DDL不同。由于这个原因,dbms_实用程序过程似乎只是默默地忽略了它

如果简化语句以删除不必要的块,则它将起作用:

...
BEGIN
    lc_stmt := 'CREATE INDEX '
               || in_index
               || ' ON '
               || in_tb
               || ' ('
               || in_columns
               || ')';

...
演示:

“受影响的”数字仍然为空,因为execute_ddl_语句不会导致设置SQL%rowcount,所以您不能依靠它来告诉您任何事情。但索引已经创建:

select object_type, object_name from user_objects where created > trunc(sysdate);

OBJECT_TYPE         OBJECT_NAME                   
------------------- ------------------------------
TABLE               TABLE_1_LOAD                  
PROCEDURE           CREATE_INDEX                  
INDEX               ON_RUN_INDEX                  

您可以使用executeimmediate运行原始语句,这实际上会设置SQL%rowcount,但由于您还没有运行任何DML,因此它实际上毫无意义。为了说明这一点,对于仍然不必要的匿名块,您得到1;如果没有块,使用与上面相同的简化语句,则得到0。

您试图通过exec_ddl_语句运行的动态语句不是ddl。它包含DDL,但嵌入在匿名PL/SQL块中,这与DDL不同。由于这个原因,dbms_实用程序过程似乎只是默默地忽略了它

如果简化语句以删除不必要的块,则它将起作用:

...
BEGIN
    lc_stmt := 'CREATE INDEX '
               || in_index
               || ' ON '
               || in_tb
               || ' ('
               || in_columns
               || ')';

...
演示:

“受影响的”数字仍然为空,因为execute_ddl_语句不会导致设置SQL%rowcount,所以您不能依靠它来告诉您任何事情。但索引已经创建:

select object_type, object_name from user_objects where created > trunc(sysdate);

OBJECT_TYPE         OBJECT_NAME                   
------------------- ------------------------------
TABLE               TABLE_1_LOAD                  
PROCEDURE           CREATE_INDEX                  
INDEX               ON_RUN_INDEX                  
您可以使用executeimmediate运行原始语句,这实际上会设置SQL%rowcount,但由于您还没有运行任何DML,因此它实际上毫无意义。为了说明这一点,对于仍然不必要的匿名块,您得到1;如果没有块,使用与上面相同的简化语句,则得到0

select object_type, object_name from user_objects where created > trunc(sysdate);

OBJECT_TYPE         OBJECT_NAME                   
------------------- ------------------------------
TABLE               TABLE_1_LOAD                  
PROCEDURE           CREATE_INDEX                  
INDEX               ON_RUN_INDEX