Виконайте сценарій за допомогою 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) s вкладку, вказану в одному рядку?
Кріс Саксон

@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 всередині команди, незалежно від того, де вона знаходиться в рядку чи ні, не може обробляти лінії з похилою косою рисою окремо на рядку в рядку.


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.


Дивіться мою відповідь, чому це не гарне рішення для операторів DDL або вбудованих косої риски.
Лей Ріффер

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.