208

本周我们在我的公司就应该如何编写 SQL 脚本进行了一些辩论。

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

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

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

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

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

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

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

4

8 回答 8

368

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

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

;结束一条 SQL 语句,而/执行当前“缓冲区”中的任何内容。因此,当您使用 a; a时/,该语句实际上会执行两次。

您可以很容易地看到使用/after 运行语句:

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

主要/是为了运行嵌入了;like CREATE PROCEDURE, CREATE FUNCTION,CREATE PACKAGE语句和任何BEGIN...END块的语句。

于 2012-04-18T10:40:08.103 回答
110

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

在 SQLPLUS 中:

  1. ;意思是“终止当前语句,执行它并将它存储到 SQLPLUS 缓冲区”
  2. <newline>在 DML (SELECT, UPDATE, INSERT,...) 语句或某些类型的 DDL (Creating Tables and Views) 语句(包含 no ;)之后,这意味着将语句存储到缓冲区但不运行它。
  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;
/
于 2014-01-15T18:16:57.560 回答
32

这是一个偏好问题,但我更喜欢看到始终使用斜线的脚本 - 这样所有“单元”工作(创建 PL/SQL 对象、运行 PL/SQL 匿名块和执行 DML 语句)都可以肉眼更容易分辨。

此外,如果您最终使用 Ant 进行部署,它将简化目标的定义以具有一致的语句分隔符。

于 2009-07-03T17:12:25.697 回答
23

几乎所有 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>)
于 2009-07-21T19:04:21.020 回答
16

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

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

于 2012-06-26T15:48:43.807 回答
0

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

于 2009-07-03T16:11:35.830 回答
0

在 sql 脚本文件中使用分号来分隔 sql 语句,这些语句告诉客户端软件(SQL*Plus、SQL Developer)要执行的单个语句是什么。

在 sql 脚本文件中使用斜线分隔 pl/sql 块,告诉客户端软件(SQL*Plus、SQL Developer)要执行的单个 pl/sql 块是什么。

当您想要执行缓冲语句时,在 SQL*Plus 命令行中使用斜杠(是的,它是没有分号的单个 sql 语句或没有斜杠的 pl/sql 块)。

于 2021-03-25T10:40:32.703 回答
0

在以“end;”结尾的语句后使用斜杠,否则不要使用它。

于 2022-01-28T06:00:08.863 回答