【问题标题】:SQLPlus is trying to drop package twiceSQLPlus 试图两次删除包
【发布时间】:2019-03-06 18:01:40
【问题描述】:

在 SQLPlus 中执行脚本时遇到了一个问题:

script.sql 包含以下几行

@some_pkg.pks
@some_pkg.pkb

drop package some_pkg;
/

调用后

> sqlplus 用户/密码@dbname @script.sql

以下消息在控制台中:

Package created.
Package body created.
Package dropped.

drop package some_pkg;
*
ERROR at line 1:
ORA-04043: object SOME_PKG does not exist

请解释一下这里发生了什么。看起来包裹被丢弃了两次。是否可以避免错误?

【问题讨论】:

  • some_pkg.pks 和 some_pkg.pkb 的内容是什么?
  • 那是因为/ 再次运行最后一条语句。简短的回答:不要在 drop 声明之后使用 / 请参阅:stackoverflow.com/a/10207695/330315

标签: sql oracle sqlplus sql-drop


【解决方案1】:

SQLplus命令执行的规则基本是:

  • 遇到分号时执行当前文本。因此,如果一行不以分号结尾,则继续收集当前文本。
  • 如果遇到DECLAREBEGIN,收集所有文字,不要在分号上执行
  • 如果遇到斜线 (/),请执行收集的文本。

那么在您的情况下,分号和斜杠都会执行DROP 语句。

要修复它,请删除斜线。

如果你有一个 PL/SQL 块,你只需要斜杠,它总是带有 END 语句。其他一切使用分号。

注意:以上规则已简化。它在实践中更复杂。

【讨论】:

  • 或者去掉分号...斜杠本身仍然会在缓冲区中执行drop命令。 (但在代码中执行此操作的方式要保持一致。)
  • 是的,我同意。但作为编写一致代码并帮助您发现错误的简单规则,我建议仅对 PL/SQL 块使用斜杠,否则使用分号。
【解决方案2】:

一些例子将有助于理解规则:

  1. 以下代码将执行一次
begin
  dbms_output.put_line('executed');
end;
/
  1. 以下代码不会执行(缺少分号)
begin
  dbms_output.put_line('executed')
end
/
  1. 以下代码将被执行两次
begin
  dbms_output.put_line('executed');
end;
/
/
  1. 以下代码将执行一次
select 1 from dual
/
  1. 以下代码将执行一次
select 1 from dual;
  1. 以下代码将被执行两次
select 1 from dual;
/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-13
    • 2019-03-03
    • 1970-01-01
    • 2020-10-13
    • 2015-05-03
    • 2011-07-05
    相关资源
    最近更新 更多