执行过程

时间:2017-09-18 19:22:02

标签: sql oracle plsql oracle11g dynamic-sql

这是我程序的代码:

drop procedure CREATE_SEQUENTIAL_TR;
CREATE OR REPLACE procedure CREATE_SEQUENTIAL_TR(table_name_pr VARCHAR)
is
    coluna_cod varchar(100 char);
begin
    select 
        COLUMN_NAME 
    into
        coluna_cod
    from 
        ALL_TAB_COLUMNS 
    where 
        TABLE_NAME = table_name_pr 
        and COLUMN_NAME like 'PK_CD%';

    execute immediate '
    drop sequence cod_' || table_name_pr ||';
    create sequence cod_' || table_name_pr ||';';

    execute immediate '
    drop trigger cod_' || table_name_pr || '_tr;
    create or replace trigger cod_' || table_name_pr || '_tr            
    before 
        UPDATE or INSERT on ' || table_name_pr || '
    for each row
    begin
        if UPDATING then
            if :new.' || coluna_cod ||' != :old.' || coluna_cod ||' then
                :new.' || coluna_cod ||' := :old.' || coluna_cod ||';
            end if;
        else -- inserting
            :new.' || coluna_cod ||' := cod_' || table_name_pr || '.nextval();
        end if; 
    end;';
end;

错误是我执行时:

--test_trigger_cod is a table name
execute create_sequential_tr(test_trigger_cod)

错误是

  

PLS-00357:表,视图或序列参考' test_trigger_cod'不   允许在这种情况下

似乎我无法在哪里使用参数?什么是解决方法?

完整错误(手动翻译):

Error starting from line : 1 on the command -
BEGIN create_sequential_tr(teste_trigger_cod); END;
Error report: -
ORA-06550: line 1, column 28:
PLS-00357: Reference 'TESTE_TRIGGER_COD' to Table, View ou Sequence not allowed in this context
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
06550. 00000 -  "line %s, column %s:\n%s"
*Cause:    Usually a PL/SQL compilation error.
*Action:

1 个答案:

答案 0 :(得分:3)

EXECUTE IMMEDIATE运行单个SQL语句。您正在尝试每次调用执行多个语句。所以你需要转过来......

execute immediate '
    drop sequence cod_' || table_name_pr ||';
    create sequence cod_' || table_name_pr ||';'; 

......进入这个:

execute immediate 'drop sequence cod_' || table_name_pr ;
execute immediate 'create sequence cod_' || table_name_pr ;

对触发器语句执行相同的操作。

作为一般观察,动态SQL很难,因为编译错误会成为运行时错误。让自己轻松一点,并使用变量来汇编语句;这种方法为您提供了支持调试的功能,例如:

l_stmt := 'drop sequence cod_' || table_name_pr ;
dbms_output.put_line('about to execute :: ' || l_stmt);
execute immediate l_stmt ;