使用 Alter 命令的 Oracle 存储过程

发布于 2024-08-25 21:56:32 字数 112 浏览 6 评论 0原文

我正在尝试构建一个 Oracle 存储过程,它将接受表名作为参数。然后该过程将重建表上的所有索引。

我的问题是在存储过程中使用 ALTER 命令时出现错误,就好像 PLSQL 不允许该命令一样。

I am trying to build an Oracle stored procedure which will accept a table name as a parameter. The procedure will then rebuild all indexes on the table.

My problem is I get an error while using the ALTER command from a stored procedure, as if PLSQL does not allow that command.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

风吹雪碎 2024-09-01 21:56:32

使用execute立即语句在PL/SQL内部执行DDL。

create procedure RebuildIndex(index_name varchar2) as
begin
   execute immediate 'alter index ' || index_name || ' rebuild';
end;

我测试了这段代码;有用。

Use the execute immediate statement to execute DDL inside PL/SQL.

create procedure RebuildIndex(index_name varchar2) as
begin
   execute immediate 'alter index ' || index_name || ' rebuild';
end;

I tested this code; it works.

最美的太阳 2024-09-01 21:56:32

文档。

通过架构对象名称作为参数

假设您需要一个程序
接受任何数据库的名称
表,然后从您的表中删除该表
架构。您必须使用 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;
/

使用串联来构建字符串,
而不是试图通过桌子
通过 name 作为绑定变量
USING 子句。

此外,如果您需要致电
其名称未知的过程,直到
运行时,可以传递一个参数
确定程序。为了
例如,下面的过程可以
调用另一个过程(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;
/

Documentation.

Passing Schema Object Names As Parameters

Suppose you need a procedure that
accepts the name of any database
table, then drops that table from your
schema. You must build a string with a
statement that includes the object
names, then use EXECUTE IMMEDIATE to
execute the statement:

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;
/

Use concatenation to build the string,
rather than trying to pass the table
name as a bind variable through the
USING clause.

In addition, if you need to call a
procedure whose name is unknown until
runtime, you can pass a parameter
identifying the procedure. For
example, the following procedure can
call another procedure (drop_table) by
specifying the procedure name when
executed.

CREATE PROCEDURE run_proc (proc_name IN VARCHAR2, table_name IN VARCHAR2) ASBEGIN
   EXECUTE IMMEDIATE 'CALL "' || proc_name || '" ( :proc_name )' using table_name;
END;
/

If you want to drop a table with the
drop_table procedure, you can run the
procedure as follows. Note that the
procedure name is capitalized.

CREATE TABLE employees_temp AS SELECT last_name FROM employees;
BEGIN 
  run_proc('DROP_TABLE', 'employees_temp'); 
END;
/
空心空情空意 2024-09-01 21:56:32

这里有几种可能性。首先,您必须将 SQL 视为动态 SQL。其次,Oracle DDL 语句不能在事务中运行(或者,它们终止当前事务并且本身不能回滚)。这可能会影响您是否可以在存储过程中使用它们,或者可以在何处使用包含它们的存储过程。

如果以上都不适用 - 很容易有其他东西误入歧途 - 我建议发布一些代码。

Here are a couple of possibilities. First, you would have to treat the SQL as dynamic SQL. Second, Oracle DDL statements cannot be run in a transaction (or, they terminate the current transaction and cannot themselves be rolled back). This may affect whether you can use them in stored procedures, or where you can use stored procedures that contain them.

If none of the above apply at all - there could easily be something else astray - I suggest posting some code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文