Выполните сценарий с SQLPlus, содержащий пробелы, точки с запятой и косую черту

15

Иногда я получаю сценарий, который будет нормально работать в SQL Developer или Toad, но требует модификации для успешного запуска из SQL * Plus. Вот пример наихудшего случая, содержащий несколько операторов, каждое из которых содержит пустые строки, точки с запятой и косую черту:

INSERT INTO t1 VALUES ('a

;
/
');

INSERT INTO t1 VALUES ('b

;
/
');

DELETE FROM t1 WHERE c1 = 'c

;
/
';

По разным причинам эти операторы должны запускаться из SQL * Plus. Пустые строки легко решить с помощью простого ...

set sqlblanklines on

Я знаю, что их sqlterminatorможно изменить и / или отключить, но оба требуют изменения кода, первый перемещает проблему, не решая ее, и не решает проблему встроенной косой черты.

Наилучшим ответом был бы способ разрешить выполнение этих операторов без изменений, изменяя каким-либо образом среду (как это делает sqlblanklines). Если это невозможно, возможно, есть способ программно изменить сценарии. Я пытаюсь избежать ручных изменений.

Ли Риффель
источник
Эта проблема может легко возникнуть при использовании командной строки SQLPLUS. Пока вы находитесь внутри программы SQLPLUS, редактор командной строки также все еще активен. В результате элементы, которые имеют отношение к редактору командной строки (пробелы интерпретируются как команда / переменная, точки с запятой рассматриваются как конец команды). Вот почему наличие «@» в пароле не вызывает ничего, кроме душевной боли, когда вы пытаетесь войти (все справа от @ рассматривается как имя БД). Во время крупного развертывания мы обнаружили проблемы с пробелами, которые вынуждали нас развертывать вещи через TOAD. SQLPLUS был бесполезен для
TomV
Спасибо за ваши мысли. Итак, чтобы уточнить ваш ответ, что то, что я запрашиваю, невозможно?
Ли Риффель
Можете ли вы преобразовать возврат каретки внутри строки в строку вставки chr (10) в одну строку?
Крис Саксон
@ChrisSaxon Я могу, но эта проблема заключается в том, как различить возвращаемые значения, которые должны быть закодированы, и возвращаемые данные, которые необходимо оставить в одиночестве как часть синтаксиса. Если у вас есть способ сделать это, пожалуйста, опубликуйте это как ответ.
Ли Риффель

Ответы:

8

Вы можете сделать большую часть этого, используя login.sql. login.sql выполняется во время - удивительно - входа в систему и загружается из вашего SQLPATH или текущего каталога. Для приведенных вами примеров вы действительно выбрали худший вариант.

Проблема в том, что sqlterminator. Что бы вы там ни указали, косая черта поддерживается как бесплатный sqlterminator. Кроме того, sqlplus сначала сканирует sqlterminator и делает это перед сканированием до строкового терминатора. Ошибка, если вы спросите меня. Косая черта может использоваться в строке, если она не одинока в отдельной строке. Как только sqlplus находит символ, указанный как sqlterminator, он игнорирует все остальное и прекращает чтение.

Косая черта может быть обработана, пока она не одна на линии.

login.sql содержит:

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 содержит:

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

запустите скрипт:

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.

Не нужно возиться с блоками начала / конца. Не может обрабатывать sqlterminator внутри команды, независимо от того, где она находится, в строке или нет, не может обрабатывать строки с косой чертой в строке в строке.

ik_zelf
источник
1
Спасибо за доказательство. Я уже использую настройки файла login.sql аналогичным образом. Так что в основном это подтверждает, что то, чего я хотел бы сделать, не может быть сделано.
Ли Риффель
1
Небольшое изменение заключается в использовании скрипта бегуна, который выполняет настройки и вызывает реальный скрипт. Станет sqlplus leigh / leigh @ orcl @runner leigh. Это немного более гибко, чем login.sql
ik_zelf
1

Операторы вставки с пустыми строками и точками с запятой завершатся успешно, если поместить их в блоки BEGIN ... END. Это изменение может быть выполнено с использованием сценария, но сценарий завершится ошибкой, если он содержит операторы DDL, которые нельзя выполнить внутри блока без немедленного выполнения.

Это решение также не решает внедренную проблему.

Ли Риффель
источник
В прошлом я использовал скрипт perl / DBD, чтобы избежать sqlplus.
Рад
@Phil Спасибо, но SQLPlus отлично работает в 99,9% случаев, поэтому я бы не стал добавлять в этот инструмент другой инструмент.
Ли Риффель
1

Мой обходной путь:

         begin
             INSERT INTO t1 VALUES ('a

             ;
             ');
         end;
         /

Кажется, что терминатор команды игнорируется внутри оператора body.

Bocian
источник
См. Мой ответ, почему это не очень хорошее решение для операторов DDL или встроенных слешей.
Ли Риффель
-1
set sqlterminator OFF
<...>
set sqlterminator ON
user28627
источник
1
И как это поможет?
Дезсо,