Избегайте повторения одного и того же WITH в нескольких SPOOL в сценарии SQL * Plus без использования CREATE - PullRequest
0 голосов
/ 02 июля 2019

Я спулирую из сценария SQL * Plus множество SELECT для разделения CSV, большинство из которых ПРИСОЕДИНЯЮТСЯ к одному и тому же SELECT, который я поместил как WITH перед SELECT в каждом SPOOL, чтобы хотя бы иметь возможность легко найти и заменить.

Теперь я пытаюсь избавить скрипт от повторения кода и оптимизировать производительность, возможно, сохраняя результаты повторного SELECT и повторно используя их в каждом SPOOL.

Я пытался использовать переменные для хранения результатов SELECT, который повторяется как WITH, но я не могу смешать SPOOL SQL * Plus с кодом PL / SQL (используя SPOOL внутри DECLARE BEGIN / END блок завершается неудачно, в командной строке выводится только число 28 Сначала я подумал, что нужны временные таблицы, но есть только доступ только для чтения, поэтому нет DDL, как CREATE / ALTER и т. Д.

SET MARKUP CSV ON
-- omitting delimiter and other SQL*Plus options set

SPOOL C:\test\1.csv

WITH Y AS ( SELECT * FROM Z )
SELECT * FROM X JOIN Y ON Y.W = X.W
;
SPOOL OFF

SPOOL C:\test\2.csv

WITH Y AS ( SELECT * FROM Z )
SELECT * FROM W JOIN Y ON Y.X = W.X
;
SPOOL OFF

-- many other different spools joining on the same WITH SELECT

exit;

Этот код работает нормально, но я бы предпочел не повторять один и тот же WITH, так как это снижает производительность и делает код рутинной задачей для поддержки / работы. Тем не менее, главная проблема здесь - это повторение кода, а не обязательно снижение производительности, по крайней мере, на данный момент, хотя уродливо, когда сервер повторяет одни и те же запросы снова и снова.

Очевидно, я не грамотен в Oracle / PL / SQL.

Ответы [ 2 ]

1 голос
/ 02 июля 2019

Было бы полезно, если бы вы (или кто-то еще) могли создать представление как

create view v_y
as
SELECT * FROM Z       --> this is your "Y" CTE

Я предполагаю, что SELECT * FROM Z более сложный, чем это простое утверждение, поэтому - если ничего - ваш код будет выглядеть красивее. Посмотрите, может ли администратор баз данных создать для вас представление.

Это также означает, что вы полностью избегаете CTE и напрямую соединяете таблицы с представлением v_y.


... завершается неудачно, в командной строке выводится только число "28"

Это означает, что вы должны завершить этот блок PL / SQL косой чертой. Или просто введите косую черту сейчас и нажмите ввод:

28  /            --> now press enter

В любом случае, SPOOL - команда SQL * Plus - не будет работать в процедурах PL / SQL. Но вы можете создать файл, используя пакет UTL_FILE. Это не так просто, как SPOOL, поскольку вам следует предоставить право использовать этот пакет, администратор БД должен создать каталог (объект Oracle), который указывает на каталог на жестком диске сервера базы данных, предоставляя вам права доступа к нему (каталог) , Это далеко не невозможно , но вы не можете сделать это самостоятельно.

Возможно, вы бы предпочли, чтобы они создали это представление для вас, а?

0 голосов
/ 03 июля 2019

Чтобы ответить на следующие вопросы:

, но я не могу смешать SQL * Plus SPOOL с PL / SQL-кодом (использование SPOOL внутри блока DECLARE BEGIN / END не удаетсяв командной строке выводится только число «28»)

Вы можете использовать блок Spool и PL / SQL, используя следующую технику:

-- test.sql file

spool tejash_1.txt

declare
 cursor c_emp is 
 select seq, req from table1;

begin
  for r_emp in c_emp loop
    dbms_output.put_line(r_emp.seq || ' ' || r_emp.req);
  end loop;

end;
/

spool off

-- end of test.sql file


-- Command to execute in SQL*Plus
SQL> set serverout on
SQL> SET echo off
SQL> SET feedback off
SQL> SET term off
SQL> @test.sql

-- output in tejash_1.txt file
001 X1 
002 X1 
003 X1 
004 X1 
-- End of output in tejash_1.txt file

Cheers!!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...