Генерация скрипта SQL * Plus с использованием SQL * Plus - PullRequest
3 голосов
/ 10 ноября 2010

Я хочу создать множество сценариев SQL * Plus, запрашивая словарь данных, но я сталкиваюсь с некоторыми проблемами и подозреваю, что упускаю что-то очевидное.

Например, когда я выполняю следующее в SQL * Plus, я получаю ORA-01756: quoted string not properly terminated:

SQL> SPOOL myscript.sql
SQL> SELECT q'[SPOOL log
  2  SELECT COUNT(*) FROM DUAL;
ERROR:
ORA-01756: quoted string not properly terminated

Я попытался использовать символ продолжения строки, чтобы избежать этой ошибки, но он помещает символ продолжения в вывод:

SQL> SELECT q'[SPOOL log
  2  SELECT COUNT(*) FROM DUAL; -
  3  PROMPT Done.
  4  ]' FROM DUAL;
SPOOL log
SELECT COUNT(*) FROM DUAL; -
PROMPT Done.

Заметьте, как вывод имеет - после DUAL;? Я не хочу этого в сгенерированном скрипте.

Один из способов обойти это - объединить множество вызовов функций CHR () для генерации точек с запятой и перевода строки; но я надеюсь, что мне это не нужно, потому что эти генерируемые скрипты очень длинные, а наличие битов вроде ]'||CHR(59)||CHR(10)||q'[, разбросанных по всему коду, делает его очень уродливым и проблематичным.

(я использую SQL * Plus Release 11.2.0.1.0 Production, подключаясь к экземпляру 11gR2.)

Ответы [ 5 ]

2 голосов
/ 10 ноября 2010

Проблема в том, что SQL * Plus интерпретирует ваш первый ; как терминатор для команды.Возможно, вы заметили, что если вы записываете свои команды в текстовый файл и выполняете это (или редактируете его в текстовом редакторе с помощью SQL * Plus), это работает.если вы действительно хотите это сделать (кажется маловероятным, если они будут очень длинными!), вы можете отключить автоматическое определение терминатора с помощью SET SQLTERMINATOR off.Обратите внимание, что вы должны сообщить SQL * Plus, что все готово и что оно должно выполняться с инструкцией /, поскольку вторая ; также игнорируется.

SQL> SPOOL myscript.sql
SQL> SET SQLTERMINATOR off
SQL> SELECT q'[SPOOL log
  2  SELECT COUNT(*) FROM DUAL;
  3  PROMPT Done.
  4  ]' FROM DUAL
  5  /
SPOOL log
SELECT COUNT(*) FROM DUAL;
PROMPT Done.

Если вы 'При построении их из словаря данных, другой вариант - использовать PL / SQL для выполнения запросов и манипуляций и dbms_output для получения результата, который вы собираетесь спутировать, если конечный размер файла не будет превышать буферпределы.

1 голос
/ 10 ноября 2010

Когда я хочу создать сценарий из БД, я предпочитаю писать файл с использованием пакета UTL_FILE вместо буферизации вывода SQL * Plus.Это не точно , что вы хотите, но я считаю, что элемент управления гораздо менее хлопотный, чем попытка написания SQL-скриптов, которые правильно форматируют.

0 голосов
/ 11 июня 2014

Для дальнейшего использования, вместо того, чтобы возиться с SET SQLTERMINATOR off при использовании sql плюс , используйте следующую ниже, чтобы вам не пришлось беспокоиться о каком-либо специальном символе терминатора sql внутри строкового литералатело.

BEGIN
INSERT INTO SOME_TABLE (q'[ 

Now;
You;
Can '
Do "'"';' ;;;
any character? *

]');
END;
/
0 голосов
/ 10 ноября 2010

Вам нужно увидеть http://download.oracle.com/docs/cd/A97630_01/server.920/a90842/ch13.htm

SET CMDS[EP] {;|c|ON|OFF}

Sets the non-alphanumeric character used to separate multiple SQL*Plus commands entered on one line to c. ON or OFF controls whether you can enter multiple commands on a line. ON automatically sets the command separator character to a semicolon (;).
0 голосов
/ 10 ноября 2010

Вы можете использовать getddl в пакете dbms_metada или в моем пакете: http://github.com/xtender/XT_SVN

...