我们本周在我的公司一直在讨论如何编写SQL脚本 .
背景:我们的数据库是Oracle 10g(很快升级到11) . 我们的DBA团队使用SQLPlus将脚本部署到 生产环境 环境 .
现在,我们最近部署失败,因为它使用了分号和正斜杠( /
) . 分号在每个语句的末尾,斜杠在语句之间 .
alter table foo.bar drop constraint bar1;
/
alter table foo.can drop constraint can1;
/
稍后在脚本中添加了一些触发器,创建了一些视图以及一些存储过程 . 同时使 ;
和 /
导致每个语句运行两次导致错误(特别是在插入时,这需要是唯一的) .
在SQL Developer中,这不会发生,在TOAD中这不会发生 . 如果您运行某些命令,如果没有 /
,它们将无法工作 .
在PL / SQL中,如果你有子程序(DECLARE,BEGIN,END),使用的分号将被视为子程序的一部分,因此你必须使用斜杠 .
所以我的问题是:如果您的数据库是Oracle,那么编写SQL脚本的正确方法是什么?既然你知道你的数据库是Oracle应该总是使用 /
吗?
6 回答
几乎所有Oracle部署都是通过SQL * Plus(DBA使用的奇怪的小命令行工具)完成的 . 在SQL * Plus中,一个单独的斜杠基本上意味着“重新执行我刚刚执行的最后一个SQL或PL / SQL命令” .
看到
经验法则是使用斜线来做
BEGIN .. END
或你可以使用CREATE OR REPLACE
的东西 .对于需要独特使用的插件
这是一个偏好问题,但我更喜欢看到一直使用斜杠的脚本 - 这样所有“单元”工作(创建PL / SQL对象,运行PL / SQL匿名块,执行DML语句)都可以用眼睛更容易挑选出来 .
此外,如果您最终转移到类似Ant的部署,它将简化目标的定义以具有一致的语句分隔符 .
根据我的理解,所有SQL语句都不需要正斜杠,因为它们将在分号结束时自动运行,包括DDL,DML,DCL和TCL语句 .
对于其他PL / SQL块,包括过程,函数,包和触发器,因为它们是多行程序,Oracle需要一种方法来知道何时运行块,所以我们必须在每个块的末尾写一个正斜杠让Oracle运行它 .
我只在每个脚本的末尾使用正斜杠,告诉sqlplus没有更多的代码行 . 在脚本中间,我不使用斜杠 .
我知道这是一个老线程,但我偶然发现它,我觉得这还没有完全解释 .
SQL * Plus在
/
和;
的含义之间存在巨大差异,因为它们的工作方式不同 .;
结束SQL语句,而/
执行当前"buffer"中的任何内容 . 因此,当您使用;
and a/
时,该语句实际执行了两次 .在运行语句后,您可以轻松地看到使用
/
:在这种情况下,实际上会注意到错误 .
但假设有一个像这样的SQL脚本:
这是从SQL * Plus内部运行然后这将是非常混乱:
/
主要用于运行嵌入;
的语句,如CREATE PROCEDURE
语句 .我想澄清
;
和/
之间的更多用法在SQLPLUS中:
;
表示"terminate the current statement, execute it and store it to the SQLPLUS buffer"在D.M.L.之后
<newline>
(SELECT,UPDATE,INSERT,...)语句或某些类型的D.D.L(创建表和视图)语句(不包含;
),这意味着,将语句存储到缓冲区但不运行它 .输入缓冲区中的语句后
/
(空白<newline>
)表示“在缓冲区中运行D.M.L.或D.D.L.或PL / SQL .RUN
或R
是一个sqlsplus命令,用于在缓冲区中显示/输出SQL并运行它 . 它不会终止SQL语句 .在进入D.M.L期间
/
或D.D.L.或PL / SQL表示"terminate the current statement, execute it and store it to the SQLPLUS buffer"NOTE: 因为
;
用于PL / SQL结束语句;
不能被SQLPLUS用来表示"terminate the current statement, execute it and store it to the SQLPLUS buffer"因为我们希望整个PL / SQL块完全在缓冲区中,然后执行它 . PL / SQL块必须以: