it-swarm-eu.dev

Führen Sie ein Skript mit SQLPlus aus, das Leerzeichen, Semikolons und Schrägstriche enthält

Gelegentlich erhalte ich ein Skript, das in SQL Developer oder Toad einwandfrei ausgeführt wird, jedoch Änderungen erfordert, um erfolgreich in SQL * Plus ausgeführt zu werden. Hier ist ein Worst-Case-Beispiel mit mehreren Anweisungen mit Leerzeilen, Semikolons und Schrägstrichen:

INSERT INTO t1 VALUES ('a

;
/
');

INSERT INTO t1 VALUES ('b

;
/
');

DELETE FROM t1 WHERE c1 = 'c

;
/
';

Aus verschiedenen Gründen müssen diese Anweisungen in SQL * Plus ausgeführt werden. Die leeren Zeilen lassen sich leicht mit einem einfachen ...

set sqlblanklines on

Mir ist bekannt, dass sqlterminator geändert und/oder deaktiviert werden kann, aber beide würden Änderungen am Code erfordern. Ersteres verschiebt das Problem, ohne es zu lösen, und behebt auch nicht das Problem mit eingebetteten Schrägstrichen.

Die beste Antwort wäre eine Möglichkeit, diese Anweisungen ohne Änderung ausführen zu lassen, indem die Umgebung auf irgendeine Weise geändert wird (wie dies bei sqlblanklines der Fall ist). Wenn dies nicht möglich ist, gibt es möglicherweise eine Möglichkeit, die Skripte programmgesteuert zu ändern. Ich versuche, manuelle Änderungen zu vermeiden.

15
Leigh Riffel

Sie können das meiste davon tun, indem Sie eine login.sql verwenden. login.sql wird während der - überraschenden - Anmeldung ausgeführt und aus Ihrem SQLPATH oder dem aktuellen Verzeichnis geladen. Für die Beispiele, die Sie gegeben haben, haben Sie wirklich den schlimmsten Fall gewählt.

Problem ist der sqlterminator. Was auch immer Sie dort eingeben, der Schrägstrich wird als kostenloser SQL-Minator beibehalten. Daneben sucht sqlplus zuerst nach dem sqlterminator und führt dies vor dem Scannen zum String-Terminator durch. Ein Fehler, wenn Sie mich fragen. Der Schrägstrich kann in einer Zeichenfolge verwendet werden, solange er nicht allein in einer separaten Zeile steht. Sobald sqlplus das als sqlterminator angegebene Zeichen findet, ignoriert es alles andere und hört auf zu lesen.

Der Schrägstrich kann behandelt werden, solange er nicht alleine in einer Zeile steht.

login.sql enthält:

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 enthält:

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

führen Sie das Skript aus:

sqlplus leigh/[email protected] @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.

Sie müssen nicht mit Start-/Endblöcken herumspielen. Der Befehl sqlterminator innerhalb des Befehls kann nicht verarbeitet werden, unabhängig davon, wo er sich in einer Zeichenfolge befindet oder nicht. Er kann keine Zeilen mit Schrägstrich allein in einer Zeile in einer Zeichenfolge verarbeiten.

8
ik_zelf

Meine Problemumgehung:

         begin
             INSERT INTO t1 VALUES ('a

             ;
             ');
         end;
         /

Es scheint, als würde der Befehlsabschluss in der body-Anweisung ignoriert.

1
Bocian

Das Einfügen von Anweisungen mit Leerzeilen und Semikolons ist erfolgreich, wenn sie in BEGIN ... END-Blöcken platziert werden. Diese Änderung könnte mithilfe eines Skripts vorgenommen werden. Das Skript schlägt jedoch fehl, wenn es DDL-Anweisungen enthält, die nicht innerhalb eines Blocks ausgeführt werden können, ohne sofort ausgeführt zu werden.

Diese Lösung behebt auch das Embedded/Problem nicht.

1
Leigh Riffel