Quando preciso usar um ponto-e-vírgula ou uma barra no Oracle SQL?

179

Temos discutido esta semana na minha empresa sobre como devemos escrever nossos scripts SQL.

Antecedentes: Nosso banco de dados é Oracle 10g (atualizando para 11 em breve). Nossa equipe de DBA usa o SQLPlus para implantar nossos scripts em produção.

Agora, tivemos uma implantação recentemente que falhou porque usava ponto e vírgula e barra ( /). O ponto-e-vírgula estava no final de cada declaração e a barra estava entre as declarações.

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

Alguns gatilhos foram adicionados posteriormente no script, algumas visualizações criadas e alguns procedimentos armazenados. Ter tanto o ;eo /causada cada declaração para executar duas vezes causando erros (especialmente nas inserções, que precisavam ser único).

No SQL Developer isso não acontece, no TOAD isso não acontece. Se você executar certos comandos, eles não funcionarão sem os /mesmos.

No PL / SQL, se você tiver um subprograma (DECLARE, BEGIN, END), o ponto-e-vírgula usado será considerado como parte do subprograma, portanto, você deve usar a barra.

Portanto, minha pergunta é a seguinte: se seu banco de dados é Oracle, qual é a maneira correta de escrever seu script SQL? Como você sabe que seu banco de dados é Oracle, você deve sempre usar o /?

amischiefr
fonte
1
Caso alguém esteja fazendo uma exportação de banco de dados com o SQLDeveloper, existe uma caixa de seleção chamada "Terminator" que, quando selecionada, usa ponto e vírgula para finalizar cada instrução. Esta opção é selecionada por padrão. Desmarque para remover vírgulas e para evitar execução de instrução duplicado
Ruslans Uralovs
7
Apenas para açoitar inutilmente esse antigo thread até a morte, mencionarei que a linguagem SQL não possui ponto e vírgula. É apenas o caractere terminador padrão no SQL * Plus (você pode definir sqlterminatorpara !se quiser) e esta convenção tende a ser seguido por outras ferramentas. A linguagem PL / SQL, no entanto, usa ponto-e-vírgula como um elemento de sintaxe obrigatório.
William Robertson

Respostas:

31

É uma questão de preferência, mas eu prefiro ver scripts que usam consistentemente a barra - dessa forma, todas as "unidades" de trabalho (criando um objeto PL / SQL, executando um bloco anônimo PL / SQL e executando uma instrução DML) podem ser escolhido mais facilmente a olho nu.

Além disso, se você eventualmente mudar para algo como Ant para implantação, simplificará a definição de destinos para ter um delimitador de instrução consistente.

dpbradley
fonte
1
esta resposta não explica o porquê /ou ;a resposta de @a_horse_with_no_name ou @Mr_Moneybags para mais contexto
Kay
333

Sei que esse é um tópico antigo, mas apenas me deparei com ele e acho que isso não foi explicado completamente.

Há uma enorme diferença no SQL * Plus entre o significado de a /e a ;porque eles funcionam de maneira diferente.

O ;finaliza uma instrução SQL, enquanto o /executa o que estiver no "buffer" atual. Então, quando você usa um ; e um /a declaração é realmente executada duas vezes.

Você pode ver facilmente usando /uma instrução depois de executar:

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

Nesse caso, percebe-se o erro.


Mas supondo que exista um script SQL como este:

drop table foo;
/

E isso é executado no SQL * Plus, então isso será muito confuso:

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

A /é necessária principalmente para executar instruções que têm incorporados ;como uma CREATE PROCEDUREdeclaração.

um cavalo sem nome
fonte
2
@amis, sou novo no Oracle e entro no mesmo problema. Esta pergunta é muito útil, mas todas as respostas deram uma explicação sobre o "porquê" e não a "melhor maneira" de trabalhar ou alguma maneira de contornar isso. Então, se eu entendi direito, não há como ter apenas um script e mantê-lo utilizável para todas as ferramentas ... ou você descobre alguma maneira?
ceinmart
5
@ceinmart: a "melhor maneira" é definir uma (e apenas uma) ferramenta para executar scripts SQL - e a "correção" de um script é validada usando essa ferramenta. Semelhante a ter um compilador para a linguagem de programação ou de uma versão específica do seu ambiente de tempo de execução (Java 7, .Net 4.0, PHP 5.x, ...)
a_horse_with_no_name
1
Boa resposta. Sou apenas eu ou o Oracle é pateta e arcaico em comparação com outros bancos de dados? Eu usei muito o Sybase e parece muito mais intuitivo.
splashout
1
@splashout: bem, se você quiser executar instruções que contêm o delimitador padrão ( ;), então você precisa encontrar uma maneira de especificar um delimitador alternativo
a_horse_with_no_name
97

Eu queria esclarecer um pouco mais de uso entre o ;e o/

No SQLPLUS:

  1. ; significa "encerrar a instrução atual, executá-la e armazená-la no buffer SQLPLUS"
  2. <newline>após uma instrução DML (SELECT, UPDATE, INSERT, ...) ou alguns tipos de instruções DDL (Criando tabelas e exibições) (que não contêm nenhuma ;), significa armazenar a instrução no buffer, mas não a executa.
  3. /depois de inserir uma instrução no buffer (com um espaço em branco <newline>) significa "executar o DML ou DDL ou PL / SQL no buffer.
  4. RUNou Ré um comando sqlsplus para mostrar / gerar o SQL no buffer e executá-lo. Não terminará uma instrução SQL.
  5. / durante a entrada de um DML ou DDL ou PL / SQL significa "encerrar a instrução atual, execute-a e armazene-a no buffer SQLPLUS"

NOTA: Como ;são usadas para o PL / SQL finalizar, uma instrução ;SQLPLUS não pode ser usada para significar "finalizar a instrução atual, execute-a e armazene-a no buffer SQLPLUS" porque queremos que todo o bloco PL / SQL esteja completamente no buffer e execute-o. Os blocos PL / SQL devem terminar com:

END;
/
Mr_Moneybags
fonte
22

Quase todas as implantações do Oracle são feitas através do SQL * Plus (aquela pequena e estranha ferramenta de linha de comando que seu DBA usa). E no SQL * Plus, uma barra solitária significa basicamente "reexecutar o último comando SQL ou PL / SQL que acabei de executar".

Vejo

http://ss64.com/ora/syntax-sqlplus.html

A regra prática seria usar barras com coisas que fazem BEGIN .. ENDou onde você pode usar CREATE OR REPLACE.

Para pastilhas que precisam ser de uso exclusivo

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>)
jva
fonte
14

Pelo meu entendimento, todas as instruções SQL não precisam de barra, pois serão executadas automaticamente no final de ponto-e-vírgula, incluindo instruções DDL, DML, DCL e TCL.

Para outros blocos PL / SQL, incluindo Procedimentos, Funções, Pacotes e Acionadores, por serem programas de várias linhas, o Oracle precisa de uma maneira de saber quando executar o bloco, portanto, precisamos escrever uma barra no final de cada bloco para deixe a Oracle executá-lo.

Jerry
fonte
1

Eu só uso a barra uma vez no final de cada script, para informar ao sqlplus que não há mais linhas de código. No meio de um script, eu não uso uma barra.

Jonathan
fonte
Você pede coisas que exijam o / (como subprogramas e gatilhos) no final? E se você tiver vários gatilhos? Fiz um teste e apenas o primeiro é executado, a menos que haja um / entre cada um. Estou esquecendo de algo?
Amischiefr
Tento evitá-lo (se possível), mas se não posso (como nos gatilhos), utilizo os pontos e vírgulas e as barras exatamente como usados ​​nos scripts oficiais que geram os esquemas de amostra do oracle: download.oracle.com/docs /cd/B19306_01/server.102/b14198/… Para o problema de inserções, tento separar os scripts que criam objetos daqueles que preenchem as tabelas.
317 Jonathan
1
Desculpe, mas isso não responde à pergunta.
DerMike 2/06