Execute um script com SQLPlus contendo espaços em branco, ponto-e-vírgula e barras


15

Ocasionalmente, recebo um script que funcionará bem no SQL Developer ou no Toad, mas requer modificações para ser executado com êxito no SQL * Plus. Aqui está um exemplo de pior caso, contendo várias instruções, cada uma com linhas em branco, ponto-e-vírgula e barras:

INSERT INTO t1 VALUES ('a

;
/
');

INSERT INTO t1 VALUES ('b

;
/
');

DELETE FROM t1 WHERE c1 = 'c

;
/
';

Por vários motivos, essas instruções precisam ser executadas no SQL * Plus. As linhas em branco são fáceis de resolver com um simples ...

set sqlblanklines on

Estou ciente de que o sqlterminatorpode ser alterado e / ou desativado, mas ambos exigiriam modificações no código, o primeiro move o problema sem resolvê-lo e nem resolve o problema da barra incorporada.

A melhor resposta seria uma maneira de permitir que essas instruções sejam executadas sem modificação, alterando o ambiente de alguma maneira (como o sqlblanklines faz). Se isso não for possível, talvez haja uma maneira de modificar programaticamente os scripts. Estou tentando evitar alterações manuais.


Esse problema pode ocorrer facilmente ao usar a execução de linha de comando do SQLPLUS. Enquanto você estiver dentro do programa SQLPLUS, o editor de linha de comando também estará ativo. Como resultado, itens relevantes para o editor de linha de comando (espaços em branco são interpretados como comando / variável, ponto-e-vírgula é visto como fim de comando). É por isso que ter um '@' em uma senha não causa nada além de sofrimento quando você tenta entrar (tudo à direita de @ é visto como o nome de um banco de dados). Durante uma grande implantação, encontramos problemas com espaços em branco que nos forçaram a implantar coisas através do TOAD. SQLPLUS foi inútil para
TomV

Obrigado por seus pensamentos. Então, para esclarecer sua resposta, o que estou solicitando é impossível?
Leigh Riffel

Você pode converter os retornos de carro na string para que a inserção do chr (10) esteja listada em uma linha?
31812 Chris Saxon

@ ChrisSaxon eu posso, mas esse problema é como distinguir retornos que devem ser codificados e retornos que precisam ser deixados em paz como parte da sintaxe. Se você tem uma maneira de fazer isso, poste-o como resposta.
Leigh Riffel

Respostas:


8

Você pode fazer isso usando um login.sql. O login.sql é executado durante o - surpreendente - login e é carregado a partir do seu SQLPATH ou diretório atual. Para os exemplos que você deu, você realmente escolheu o pior caso.

O problema é o sqlterminator. Tudo o que você coloca lá, a barra é mantida como um sqlterminator gratuito. Além disso, o sqlplus verifica primeiro o sqlterminator e faz isso antes de digitalizar para o terminador de string. Um bug se você me perguntar. A barra para frente pode ser usada em uma string, desde que não esteja sozinha em uma linha separada. Assim que o sqlplus encontra o caractere especificado como sqlterminator, ele ignora todo o resto e para de ler.

A barra para frente pode ser manipulada, desde que não esteja sozinha em uma linha.

login.sql contém:

prompt run login.sql
show sqlterminator
show sqlblanklines
set sqlblanklines on
set sqlterminator ';'
show sqlterminator
show sqlblanklines
prompt ready login.sql
set echo on

leigh.sql contém:

INSERT INTO t1 VALUES ('fail bc semicolon
a;a
/
'); 

INSERT INTO t1 VALUES ('fail bc solo /


aa
/
');

INSERT INTO t1 VALUES ('ok / not solo


aa
/a
');

DELETE FROM t1 WHERE a = 'c


a/
';

execute o script:

sqlplus leigh/leigh@orcl @leigh
SQL*Plus: Release 10.2.0.4.0 - Production on Thu Aug 9 22:36:20 2012

Copyright (c) 1982, 2007, Oracle.  All Rights Reserved.


Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
Data Mining and Real Application Testing options

run login.sql
sqlterminator ";" (hex 3b)
sqlblanklines OFF
sqlterminator ";" (hex 3b)
sqlblanklines ON
ready login.sql
SQL> INSERT INTO t1 VALUES ('fail bc semicolon
  2  a;a
  3  /
ERROR:
ORA-01756: quoted string not properly terminated


SQL> ');
SP2-0042: unknown command "')" - rest of line ignored.
SQL> 
SQL> INSERT INTO t1 VALUES ('fail bc solo /
  2  
  3  
  4  aa
  5  /
ERROR:
ORA-01756: quoted string not properly terminated


SQL> ');
SP2-0042: unknown command "')" - rest of line ignored.
SQL> 
SQL> INSERT INTO t1 VALUES ('ok / not solo
  2  
  3  
  4  aa
  5  /a
  6  ');

1 row created.

SQL> 
SQL> DELETE FROM t1 WHERE a = 'c
  2  
  3  
  4  a/
  5  ';

0 rows deleted.

Não é necessário mexer nos blocos de início / fim. Não pode manipular o sqlterminator dentro do comando, não importa onde esteja, em uma sequência ou não, não pode manipular linhas com barra à frente sozinha em uma linha de uma sequência.


11
Obrigado pela prova. Eu já estou usando uma configuração de arquivo login.sql da mesma forma. Então, basicamente, isso confirma que o motivo pelo qual eu gostaria de fazer não pode ser feito.
Leigh Riffel

11
uma pequena variação é usar um script de corredor que faça as configurações e chame o script real. Se tornaria sqlplus leigh / leigh @ orcl @runner leigh. Isso é um pouco mais flexível que o
login.sql

1

Inserir instruções com linhas em branco e ponto-e-vírgula serão bem-sucedidos se colocados dentro dos blocos BEGIN ... END. Essa alteração poderia ser feita usando um script, mas o script falharia se contivesse instruções DDL que não podem ser executadas dentro de um bloco sem serem executadas imediatamente.

Essa solução também não resolve o problema / incorporado.


No passado, usei um script perl / DBD para fazer isso para evitar o sqlplus. Happy to share ...
Philᵀᴹ

@ Phil Obrigado, mas o SQLPlus funciona bem em 99,9% das situações, então prefiro não adicionar outra ferramenta à mistura.
Leigh Riffel

1

Minha solução alternativa:

         begin
             INSERT INTO t1 VALUES ('a

             ;
             ');
         end;
         /

Parece que o terminador de comando é ignorado dentro da declaração do corpo.


Veja minha resposta para saber por que essa não é uma boa solução para instruções DDL ou barras incorporadas.
Leigh Riffel

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.