首页 文章

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

提问于
浏览
154

我们本周在我的公司一直在讨论如何编写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 回答

  • 73

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

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

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

  • 22

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

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

  • 12

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

  • 29

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

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

    ; 结束SQL语句,而 / 执行当前"buffer"中的任何内容 . 因此,当您使用 ; and 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
    

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

    但假设有一个像这样的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
    

    / 主要用于运行嵌入 ; 的语句,如 CREATE PROCEDURE 语句 .

  • 1

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

    在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 .

    • RUNR 是一个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块必须以:

    END;
    /
    

相关问题