我正在尝试构建一个Oracle存储过程,它将接受一个表名作为参数。然后,该过程将重建表中的所有索引。
我的问题是我在使用存储过程的ALTER命令时出错,就像PLSQL不允许该命令一样。
答案 0 :(得分:10)
使用execute immediate
语句在PL / SQL中执行DDL。
create procedure RebuildIndex(index_name varchar2) as
begin
execute immediate 'alter index ' || index_name || ' rebuild';
end;
我测试了这段代码;它有效。
答案 1 :(得分:4)
将架构对象名称作为参数传递
假设您需要一个程序 接受任何数据库的名称 表,然后从你的表中删除该表 架构。你必须用a构建一个字符串 包含该对象的语句 名称,然后使用EXECUTE IMMEDIATE 执行声明:
CREATE TABLE employees_temp AS SELECT last_name FROM employees;
CREATE PROCEDURE drop_table (table_name IN VARCHAR2) AS
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE ' || table_name;
END;
/
使用连接来构建字符串, 而不是试图通过表 通过命名作为绑定变量 使用条款。
另外,如果你需要打电话给 程序,其名称未知,直到 运行时,您可以传递参数 确定程序。对于 例如,以下程序即可 通过调用另一个过程(drop_table) 在何时指定过程名称 执行。
CREATE PROCEDURE run_proc (proc_name IN VARCHAR2, table_name IN VARCHAR2) ASBEGIN
EXECUTE IMMEDIATE 'CALL "' || proc_name || '" ( :proc_name )' using table_name;
END;
/
如果你想放一张桌子 drop_table程序,你可以运行 程序如下。请注意 程序名称大写。
CREATE TABLE employees_temp AS SELECT last_name FROM employees;
BEGIN
run_proc('DROP_TABLE', 'employees_temp');
END;
/
答案 2 :(得分:2)
这里有几种可能性。首先,您必须将SQL视为动态SQL。其次,Oracle DDL语句不能在事务中运行(或者,它们终止当前事务并且不能自己回滚)。这可能会影响您是否可以在存储过程中使用它们,或者您可以使用包含它们的存储过程。
如果以上都不适用 - 很容易就会有其他误入歧途 - 我建议发布一些代码。