web-dev-qa-db-fra.com

Exécuter un script avec SQLPlus contenant des espaces, des points-virgules et des barres obliques

Parfois, j'obtiendrai un script qui fonctionnera correctement dans SQL Developer ou Toad, mais qui nécessite une modification pour être exécuté avec succès à partir de SQL * Plus. Voici le pire exemple contenant plusieurs instructions, chacune avec des lignes vides, des points-virgules et des barres obliques:

INSERT INTO t1 VALUES ('a

;
/
');

INSERT INTO t1 VALUES ('b

;
/
');

DELETE FROM t1 WHERE c1 = 'c

;
/
';

Pour diverses raisons, ces instructions doivent être exécutées à partir de SQL * Plus. Les lignes blanches sont faciles à résoudre avec un simple ...

set sqlblanklines on

Je suis conscient que le sqlterminator peut être modifié et/ou désactivé, mais les deux nécessiteraient des modifications du code, le premier déplace le problème sans le résoudre et aucun ne résout le problème de la barre oblique intégrée.

La meilleure réponse serait de permettre à ces instructions de s'exécuter sans modification en modifiant l'environnement d'une certaine manière (comme le fait sqlblanklines). Si cela n'est pas possible, il existe peut-être un moyen de modifier par programme les scripts. J'essaie d'éviter les changements manuels.

15
Leigh Riffel

Vous pouvez faire la plupart de cela en utilisant un login.sql. login.sql est exécuté lors de la connexion - surprenante - et est chargé à partir de votre répertoire SQLPATH ou actuel. Pour les exemples que vous avez donnés, vous avez vraiment choisi le pire des cas.

Le problème est le sqlterminator. Quoi que vous y mettiez, la barre oblique est conservée comme un sqlterminator gratuit. À côté de cela, sqlplus recherche d'abord le sqlterminator et le fait avant de numériser vers le terminateur de chaîne. Un bug si vous me demandez. La barre oblique peut être utilisée dans une chaîne tant qu'elle n'est pas seule sur une ligne séparée. Dès que sqlplus trouve le caractère spécifié comme sqlterminator, il ignore tout le reste et arrête la lecture.

La barre oblique peut être gérée, tant qu'elle n'est pas seule sur une ligne.

login.sql contient:

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 contient:

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/
';

exécutez le 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.

Pas besoin de jouer avec les blocs de début/fin. Impossible de gérer sqlterminator à l'intérieur de la commande, peu importe où il se trouve, dans une chaîne ou non, ne peut pas gérer les lignes avec barre oblique seule sur une ligne dans une chaîne.

8
ik_zelf

Ma solution:

         begin
             INSERT INTO t1 VALUES ('a

             ;
             ');
         end;
         /

Il semble que le terminateur de commande soit ignoré dans l'instruction body.

1
Bocian

Les instructions d'insertion avec des lignes vides et des points-virgules réussiront si elles sont placées à l'intérieur des blocs BEGIN ... END. Cette modification pourrait être effectuée à l'aide d'un script, mais le script échouerait s'il contenait des instructions DDL qui ne peuvent pas être exécutées à l'intérieur d'un bloc sans exécution immédiate.

Cette solution ne résout pas non plus le problème intégré /.

1
Leigh Riffel