我们本周在我的公司一直在讨论如何编写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声明.
Mr_*_*ags 91
我想澄清一下;和之间的更多用法/
在SQLPLUS中:
; 表示"终止当前语句,执行它并将其存储到SQLPLUS缓冲区"<newline>在DML(SELECT,UPDATE,INSERT,...)语句或某些类型的DDL(创建表和视图)语句(包含否;)之后,这意味着将语句存储到缓冲区但不运行它./在缓冲区中输入语句后(带空格<newline>)表示" 在缓冲区中运行DML或DDL或PL/SQL".RUN或者R是一个sqlsplus命令,用于在缓冲区中显示/输出SQL并运行它.它不会终止SQL语句./ 在输入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的部署,它将简化目标的定义以具有一致的语句分隔符.
jva*_*jva 22
几乎所有Oracle部署都是通过SQL*Plus(DBA使用的奇怪的小命令行工具)完成的.在SQL*Plus中,一个单独的斜杠基本上意味着"重新执行我刚刚执行的最后一个SQL或PL/SQL命令".
看到
经验法则是使用斜线来处理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运行它.
| 归档时间: |
|
| 查看次数: |
117886 次 |
| 最近记录: |