我何时需要在Oracle SQL中使用分号与斜杠?

ami*_*efr 170 sql oracle

我们本周在我的公司一直在讨论如何编写SQL脚本.

背景:我们的数据库是Oracle 10g(很快升级到11).我们的DBA团队使用SQLPlus将脚本部署到生产环境.

现在,我们最近部署失败,因为它使用了分号和正斜杠(/).分号在每个语句的末尾,斜杠在语句之间.

alter table foo.bar drop constraint bar1;
/
alter table foo.can drop constraint can1;
/
Run Code Online (Sandbox Code Playgroud)

稍后在脚本中添加了一些触发器,创建了一些视图以及一些存储过程.同时具有;/导致每个语句运行两次导致错误(尤其是在插入,是唯一的,其需要).

在SQL Developer中,这不会发生,在TOAD中这不会发生.如果你运行某些命令,如果没有它们,它们将无法工作/.

在PL/SQL中,如果你有子程序(DECLARE,BEGIN,END),使用的分号将被视为子程序的一部分,因此你必须使用斜杠.

所以我的问题是:如果您的数据库是Oracle,那么编写SQL脚本的正确方法是什么?既然你知道你的数据库是Oracle应该总是使用/

a_h*_*ame 315

我知道这是一个老线程,但我偶然发现了它,我觉得这还没有完全解释.

SQL*Plus在a /和a 的含义之间存在巨大差异,;因为它们的工作方式不同.

;结束的SQL语句,而/无论是在当前执行"缓冲".所以当你使用a ; a /语句实际执行两次时.

您可以轻松地看到使用/后运行语句:

SQL*Plus: Release 11.2.0.1.0 Production on Wed Apr 18 12:37:20 2012

Copyright (c) 1982, 2010, Oracle.  All rights reserved.

Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
With the Partitioning and OLAP options

SQL> drop table foo;

Table dropped.

SQL> /
drop table foo
           *
ERROR at line 1:
ORA-00942: table or view does not exist
Run Code Online (Sandbox Code Playgroud)

在这种情况下,实际上会注意到错误.


但假设有一个像这样的SQL脚本:

drop table foo;
/
Run Code Online (Sandbox Code Playgroud)

这是从SQL*Plus内部运行然后这将是非常混乱:

SQL*Plus: Release 11.2.0.1.0 Production on Wed Apr 18 12:38:05 2012

Copyright (c) 1982, 2010, Oracle.  All rights reserved.


Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
With the Partitioning and OLAP options

SQL> @drop

Table dropped.

drop table foo
           *
ERROR at line 1:
ORA-00942: table or view does not exist
Run Code Online (Sandbox Code Playgroud)

/要求主要是为了运行已嵌入语句;就像一个CREATE PROCEDURE声明.

  • @ceinmart:"最好的方法"是定义一个(并且只有一个)工具来执行SQL脚本 - 并且使用该工具验证脚本的"正确性".类似于为您的编程语言编写一个编译器或运行时环境的一个特定版本(Java 7,.Net 4.0,PHP 5.x,...) (4认同)
  • @amis,我是 Oracle 的新手,遇到了同样的问题。这个问题非常有用,但所有答案都解释了“为什么”不是“最佳方式”的工作方式或解决此问题的某种方式。所以,如果我理解正确,没有办法只有一个脚本并使其可用于所有工具......或者你有什么发现吗? (2认同)
  • 好答案。是我还是 Oracle 与其他 DB 相比愚蠢而过时?我使用了很多 Sybase,它似乎更直观。 (2认同)

Mr_*_*ags 91

我想澄清一下;和之间的更多用法/

在SQLPLUS中:

  1. ; 表示"终止当前语句,执行它并将其存储到SQLPLUS缓冲区"
  2. <newline>在DML(SELECT,UPDATE,INSERT,...)语句或某些类型的DDL(创建表和视图)语句(包含否;)之后,这意味着将语句存储到缓冲区但不运行它.
  3. /在缓冲区中输入语句后(带空格<newline>)表示" 在缓冲区中运行DML或DDL或PL/SQL".
  4. RUN或者R是一个sqlsplus命令,用于在缓冲区中显示/输出SQL并运行它.它不会终止SQL语句.
  5. / 在输入DML或DDL或PL/SQL期间意味着"终止当前语句,执行它并将其存储到SQLPLUS缓冲区"

注意:因为;用于PL/SQL结束语句;不能被SQLPLUS用来表示"终止当前语句,执行它并将其存储到SQLPLUS缓冲区",因为我们希望整个PL/SQL块完全在缓冲区,然后执行它.PL/SQL块必须以:

END;
/
Run Code Online (Sandbox Code Playgroud)


dpb*_*ley 31

这是一个偏好的问题,但我更喜欢看到一直使用斜杠的脚本 - 这样所有"工作单元"(创建PL/SQL对象,运行PL/SQL匿名块,执行DML语句)都可以用眼睛更容易挑选出来.

此外,如果您最终转移到类似Ant的部署,它将简化目标的定义以具有一致的语句分隔符.

  • 这个答案没有解释为什么 ```/``` 或 ```;``` 请参阅 @a_horse_with_no_name 或 @Mr_Moneybags 的答案以获取更多上下文 (9认同)

jva*_*jva 22

几乎所有Oracle部署都是通过SQL*Plus(DBA使用的奇怪的小命令行工具)完成的.在SQL*Plus中,一个单独的斜杠基本上意味着"重新执行我刚刚执行的最后一个SQL或PL/SQL命令".

看到

http://ss64.com/ora/syntax-sqlplus.html

经验法则是使用斜线来处理BEGIN .. END您可以使用的东西CREATE OR REPLACE.

对于需要独特使用的插件

INSERT INTO my_table ()
SELECT <values to be inserted>
FROM dual
WHERE NOT EXISTS (SELECT 
                  FROM my_table
                  WHERE <identify data that you are trying to insert>)
Run Code Online (Sandbox Code Playgroud)


小智 14

根据我的理解,所有SQL语句都不需要正斜杠,因为它们将在分号结束时自动运行,包括DDL,DML,DCL和TCL语句.

对于其他PL/SQL块,包括过程,函数,包和触发器,因为它们是多行程序,Oracle需要一种方法来知道何时运行块,所以我们必须在每个块的末尾写一个正斜杠让Oracle运行它.