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

我们本周在我们公司进行了一些辩论,关于如何编写我们的SQL脚本。

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

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

 alter table foo.bar drop constraint bar1; / alter table foo.can drop constraint can1; / 

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

在SQL Developer中,这不会发生,在TOAD中这不会发生。 如果你运行某些命令,没有/它们就不能工作。

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

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

这是一个优先select的问题,但我更喜欢看到一直使用斜杠的脚本 – 这样所有工作的“单元”(创buildPL / SQL对象,运行PL / SQL匿名块并执行DML语句)都可以用眼睛更容易挑选出来。

另外,如果你最终转移到类似Ant的部署,它将简化目标的定义,使其具有一致的语句分隔符。

我知道这是一个古老的线索,但我偶然发现了这一点,我觉得这个问题还没有完全解释。

SQL * Plus在a /和a的意义上有很大的区别; 因为他们工作不同。

The ; 结束一条SQL语句,而/执行当前“缓冲区”中的任何内容。 所以当你使用一个; 而且一个语句实际上执行了两次。

你可以很容易地看到使用/运行一个语句后:

 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 

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

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

 drop table foo; / 

而这是从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 

/主要是为了运行embedded的语句; 像一个CREATE PROCEDURE语句。

我想澄清一些更多的用途之间;/

在SQLPLUS中:

  1. ; 意味着“终止当前语句,执行并将其存储到SQLPLUS缓冲区”
  2. 在DML(SELECT,UPDATE,INSERT,…)语句或某些types的DDL(创build表和视图)语句(包含no ; )之后的<newline> ,这意味着将语句存储到缓冲区但不运行它。
  3. /在将语句input到缓冲区之后(使用空白<newline> )表示“在缓冲区中运行DML或DDL或PL / SQL。
  4. RUNR是一个sqlsplus命令,用于显示/输出缓冲区中的SQL并运行它。 它不会终止一个SQL语句。
  5. /在进入DML或DDL或PL / SQL期间意味着“终止当前语句,执行并将其存储到SQLPLUS缓冲区”

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

 END; / 

几乎所有的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>) 

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

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

我只在每个脚本的末尾使用正斜杠来告诉sqlplus没有更多的代码行。 在脚本的中间,我不使用斜线。