oracle drop table(如果没有';不存在(在一行中)

oracle drop table(如果没有';不存在(在一行中),oracle,plsql,Oracle,Plsql,我正在尝试在Oracle上执行在Sql Server上执行的操作,如下所示: IF EXISTS(SELECT * FROM dbo.Scores) DROP TABLE dbo.Scores 注意,我希望避免使用多行pl sql,因为这可以在单个脚本中重复多次 最初它是作为proc编写的,但后来在Oracle中意识到proc属于一个模式,该模式需要提升权限,这是不可取的 作为计划B,我试图执行这样一个函数调用的输出 execute immediate FN_DROP_TABLE_IF_E

我正在尝试在Oracle上执行在Sql Server上执行的操作,如下所示:

IF EXISTS(SELECT * FROM   dbo.Scores) DROP TABLE dbo.Scores
注意,我希望避免使用多行pl sql,因为这可以在单个脚本中重复多次

最初它是作为proc编写的,但后来在Oracle中意识到proc属于一个模式,该模式需要提升权限,这是不可取的

作为计划B,我试图执行这样一个函数调用的输出

execute immediate FN_DROP_TABLE_IF_EXISTS('mySchema','myTable');

同样,我的目标是在一行中找到一种方法来做到这一点。上面应该返回一个表drop语句,或者若表不存在,返回一些void类型语句

没有此类表时,您必须处理异常:

create or replace procedure drop_it(pv_name in varchar2)
is
begin
 execute immediate 'drop table schema.' || pv_name ||'  purge';
exception when others then null; end;

当没有这样的表时,您必须处理异常:

create or replace procedure drop_it(pv_name in varchar2)
is
begin
 execute immediate 'drop table schema.' || pv_name ||'  purge';
exception when others then null; end;

您可以使用创建函数,或者更恰当地说,创建过程,这意味着其中的命令将以调用用户的身份运行,并具有相应的权限,而不是以过程所有者的身份运行。这样就不需要传入模式

create procedure drop_table_if_exists(p_table_name varchar2)
authid current_user
as
  e_does_not_exist exception;
  pragma exception_init(e_does_not_exist, -942);
begin
  execute immediate 'drop table ' || p_table_name;
exception
  when e_does_not_exist then
    null; -- could report if you want
end drop_table_if_exists;
/
当您可以将其称为:

exec drop_table_if_exists('my_table');
例如,如果创建一个表,然后尝试删除它两次,则在第二次尝试时不会看到异常:

create table my_table (id number);

Table MY_TABLE created.

exec drop_table_if_exists('my_table');

PL/SQL procedure successfully completed.

exec drop_table_if_exists('my_table');

PL/SQL procedure successfully completed.
您的过程还可以查询数据字典(
user\u tables
)以查看它是否存在,然后仅在它存在时删除它,而不是尝试删除并处理异常


您还需要了解区分大小写的表名和引用完整性,这将需要按特定顺序删除表。

您可以使用创建函数,或者更恰当地说,创建过程,这意味着其中的命令将作为调用用户运行,使用他们的权限-而不是作为过程所有者。这样就不需要传入模式

create procedure drop_table_if_exists(p_table_name varchar2)
authid current_user
as
  e_does_not_exist exception;
  pragma exception_init(e_does_not_exist, -942);
begin
  execute immediate 'drop table ' || p_table_name;
exception
  when e_does_not_exist then
    null; -- could report if you want
end drop_table_if_exists;
/
当您可以将其称为:

exec drop_table_if_exists('my_table');
例如,如果创建一个表,然后尝试删除它两次,则在第二次尝试时不会看到异常:

create table my_table (id number);

Table MY_TABLE created.

exec drop_table_if_exists('my_table');

PL/SQL procedure successfully completed.

exec drop_table_if_exists('my_table');

PL/SQL procedure successfully completed.
您的过程还可以查询数据字典(
user\u tables
)以查看它是否存在,然后仅在它存在时删除它,而不是尝试删除并处理异常


您还需要了解区分大小写的表名和引用完整性,这将需要按照特定顺序删除表。

executeimmediate
是一条PL/SQL语句;您真的是指SQL*Plus(和SQL Developer)
execute
语句,它只是匿名块的包装器吗?我不知道你所说的“执行函数的输出”是什么意思-如果表存在,为什么不让函数(或者实际上是本例中的过程)动态执行drop?@AlexPoole,因为执行过程将拥有很多权限。我需要它来使用执行表删除的人的上下文,以便权限仍然基于用户正确工作。如果这是我希望的工作方式,它将是正确的解决方案@AlexPoole是否可以在调用proc时告诉它使用调用程序特权?
executeimmediate
是PL/SQL语句;您真的是指SQL*Plus(和SQL Developer)
execute
语句,它只是匿名块的包装器吗?我不知道你所说的“执行函数的输出”是什么意思-如果表存在,为什么不让函数(或者实际上是本例中的过程)动态执行drop?@AlexPoole,因为执行过程将拥有很多权限。我需要它来使用执行表删除的人的上下文,以便权限仍然基于用户正确工作。如果这是我希望的工作方式,它将是正确的解决方案@AlexPoole是否可以在调用过程中随时告诉程序使用调用程序特权?是的,这正是我希望避免的:)在一个发布脚本中执行20次,并且必须记住异常捕获语法等,这太令人讨厌了。我希望我能将这些细节封装在一个程序或函数中。@SonicSoul-这是将所有这些封装到一个过程中,它的功能与我的基本相同,但有定义者的权限(默认情况下)和一个固定的模式,这并不是您想要的。还要确保你理解“清除”的含义。感谢你花时间写这封信!我有一个proc,但唯一阻止我使用它的是权限。Alex把我指给authid current_user,它实际上为我解决了问题是的,这就是我希望避免的:)在一个发布脚本中执行20次,并且必须记住异常捕获语法等,这太令人讨厌了。我希望我能将这些细节封装在一个进程或函数中。@SonicSoul-这是封装所有这些都进入到一个过程中,它做的和我的差不多,但是有定义者的权限(默认情况下)和一个固定的模式,这不是你想要的。还要确保你理解“清除”的含义。感谢你花时间写这封信!我有一个proc,但唯一阻止我使用它的是权限。Alex把我指给authid当前的用户,这实际上解决了甲烷罐的问题!我错过了这个:authid当前用户这是伟大的,将解决许多问题!非常感谢!我错过了这个:authid当前用户这是伟大的,将解决许多问题!