Pipeline oracle что это

Обновлено: 02.07.2024

Как-то раньше мне не приходилось сталкиваться с задачей, когда приходилось внутри одной табличной функции запрашивать данные из другой табличной функции в передавать их выше, но в конце концов этот момент настал.
Мне было необходимо перегрузить табличную функцию, а поскольку алгоритм обработки данных полностью повторял уже существующий я решил воспользоваться вызовом табличной функции.
Вроде бы всё просто, делай селект типа:
for foo in (select * from pipelined_function(x))
loop
pipe row (r.a, r.b, r.c . );
end loop;
Но мне хотелось больше удобства, не хотел я писать кучу этих имён в pipe row , и начались поиски решения. Слава богу знаний хватило на то, чтобы прийти вот к такому решению:


Создаём типы:
create or replace type tr_mixed as object (num number, str varchar2(15));
create or replace type tt_mixed is table of tr_mixed;
Создаём pipelined функцию, из которой в последствии будем получать данные:
create or replace function pipe_func(p_iter number)
return tt_mixed
pipelined
is
begin
for l_index in 1 .. p_iter
loop
pipe row (tr_mixed(l_index, 'str-' || l_index));
end loop;
end pipe_func;
А теперь создаём pipelined функцию, которая будет запрашивать данные из функции выше:
create or replace
function pipe_func_ext
return tt_mixed
pipelined
is
l_temp_tt tt_mixed;
begin
select cast(multiset (select * from table(pipe_func(10))) as tt_mixed)
into l_temp_tt
from dual;
for l_index in l_temp_tt.first .. l_temp_tt.last
loop
pipe row (l_temp_tt(l_index));
end loop;
end pipe_func_ext;
Вся магия заключается в псевдофункции MULTISET , которая используется только 4как аргумент псевдофункции CAST .Она позволяет извлечь из базы данных набор значений и тут же преобразовать его в коллекцию нужного типа. Синтаксис у неё такой:
select cast (multiset (select поле from таблица) as тип_коллекции) from dual
Если всё равно не понятно, то код:
select cast(multiset (select * from table(pipe_func(10))) as tt_mixed)

select tr_number(num, str)
bulk collect into l_temp_tt
from table(pipe_func(10));
Только весь кайф заключается в том, что с multiset , можно писать *
Проверяем, что всё работает:
select * from table(pipe_func_ext);

В промышленных системах часто требуется выполнить преобразования данных с использованием pl/sql кода с возможностью обращения к этим данным в sql запросе. Для этого в oracle используются табличные функции.

Табличные функции – это функции возвращающие данные в виде коллекции, к которой мы можем обратиться в секции from запроса, как если бы эта коллекция была реляционной таблицей. Преобразование коллекции в реляционный набор данных осуществляется с помощью функции table().

Однако такие функции имеют один недостаток, так как в них сначала полностью наполняется коллекция, а только потом эта коллекция возвращается в вызывающую обработку. Каждая такая коллекция храниться в памяти и в высоконагруженных системах это может стать проблемой. Так же в вызывающей обработке происходит простой на время наполнения коллекции. Решить данный недостаток призваны табличные конвейерные функции.

Конвейерными функциями называются табличные функции, которые возвращают данные в виде коллекции, но делают это асинхронно, то есть получена одна запись коллекции и сразу же эта запись отдается в вызывающий код в котором она сразу же обрабатывается. В этом случае память сохраняется, простой по времени ликвидируется.

Рассмотрим, как создаются такие функции. В данном примере будет использована учебная схема hr и три ее таблицы: employees, departments, locations.

• employees — таблица сотрудников.
• departments — таблица отделов.
• locations — таблица географического местонахождения.

Данная схема и таблицы есть в каждой базовой сборке oracle по умолчанию.

В схеме hr я создам пакет test, в нем будет реализован наш код. Создаваемая функция будет возвращать данные по сотрудникам в конкретном отделе. Для этого в спецификации пакета нужно описать тип возвращаемых данных:


• employee_id – ид сотрудника
• first_name – имя
• last_name – фамилия
• email – электронный адрес
• phone_number – телефон
• salary – зарплата
• salary_recom – рекомендуемая зарплата
• department_id – ид отдела
• department_name — наименование отдела
• city – город

Далее опишем саму функцию:


Функция принимает на вход ид отдела и возвращает коллекцию созданного нами типа t_employees_table. Ключевое слово pipelined делает эту функцию конвейерной. В целом спецификация пакета следующая:


Рассмотрим тело пакета, в нем описано тело функции get_employees_dep:


В функции мы получаем набор данных по сотрудникам конкретного отдела, каждую строчку этого набора анализируем на предмет того, что если зарплата сотрудника меньше 8 000, то рекомендуемую зарплату устанавливаем в значение 10 000, дальше каждая строчка не дожидаясь окончания наполнения всей коллекции, отдается в вызывающую обработку. Обратите внимание, что в теле функции отсутствует ключевое слово return и присутствует pipe row (rec).

Осталось вызвать созданную функцию в pl/sql блоке:


Вот так вот просто с помощью конвейерных табличных функций мы получаем возможность сделать выборку, наполненную сколько угодно сложной логикой за счет использования pl/sql кода и не просесть в плане производительности, а в ряде случаем даже ее увеличить.

Табличные функции используются для возврата PL/SQL-коллекций, которые имитируют таблицы. Они могут быть запрошены как обычные таблицы с помощью функцию TABLE во фразе FROM. Обычные табличные функции требуют, чтобы коллекции перед возвращением были полностью наполнены (населены). Так как коллекции хранятся в памяти, это может стать проблемой, поскольку на большие коллекции впустую тратится много памяти и времени в ожидании возвращения первой строки. Эти узкие возможности делают обычные табличные функции непригодными в случаях масштабных ETL-операций (ETL — Extraction Transformation Load — Извлечение-Преобразование-Загрузка). Обычные табличные функции требуют создания именованной строки и табличных типов как объектов базы данных.

Заметим, что в этом листинге строки перечислены в обратном порядке, поскольку запрос содержит фразу упорядоченности по убыванию.

Конвейерные табличные функции)
(Pipelined Table Functions

Конвейерная обработка отменяет надобность в создании огромных наборов, передавая строки по каналу из функции по мере их создания, сохраняя память и позволяя запустить последующую обработку еще до окончания генерации всех строк.

Конвейерные табличные функции включают фразу PIPELINED и используют вызов PIPE ROW, чтобы вытолкнуть строки из функции, как только они создадутся, вместо построения табличной коллекции. Заметим, что вызов RETURN пустой, поскольку нет никакой коллекции, возвращаемой из функции.

Когда ETL-операции проводятся на большом хранилище данных, наблюдается существенное повышение производительности, поскольку загрузка данных из внешних таблиц производится табличными функциями непосредственно в таблицы хранилища, избегая промежуточного размещения данных.

Исключение NO_DATA_NEEDED
(NO_DATA_NEEDED Exception)

Конвейерная табличная функция может создать больше данных, чем необходимо запросившему её процессу. Когда такое происходит, конвейерная табличная функция останавливает выполнение, порождая исключение NO_DATA_NEEDED. Оно не должно явно обрабатываться, если только в процедуру не включен обработчик исключений OTHERS.

Приведенная ниже функция возвращает 10 строк, но запрос потребовал от нее только первые 5 строк. В этом случае функция прекращает выполнение, вызывая исключение NO_DATA_NEEDED.

Если имеется обработчик исключений OTHERS, то он захватит исключение NO_DATA_NEEDED и выполнит некоторый код обработки ошибок, что не нужно.

Если вы планируете использовать обработчик исключений OTHERS, то для исключения NO_DATA_NEEDED необходимо задействовать специальное прерывание.

Исключение NO_DATA_NEEDED может быть также использовано для выполнения операций очистки (cleanup).

Сравнение использования памяти
(Memory Usage Comparison)

Следующая функция возвращает текущее значение определенной статистики. Она позволит нам сравнивать память, используемую обычными и конвейерными табличными функциями.

Сначала мы протестируем обычную табличную функцию, создав новое соединение и запросив большую коллекцию. Проверяя выделение памяти PGA как до, так и после, тест позволит нам увидеть, сколько памяти было выделено в результате проведения теста.

Затем мы повторим тест для конвейерной табличной функции.

Сокращение памяти, используемой конвейерной табличной функцией, обусловлено тем, что она не требует разместить целую коллекцию в памяти.

Кардинальность
(Cardinality)

Oracle оценивает кардинальность (мощность, количество элементов) конвейерной табличной функции, базируясь на размере блока базы данных. Когда используется размер блока по умолчанию, оптимизатор всегда предполагает, что кардинальность - 8168 строк.

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

  • хинт CARDINALITY (9i+): Недокументирован (Undocumented)
  • хинт OPT_ESTIMATE (10g+): Недокументирован (Undocumented)
  • хинт DYNAMIC_SAMPLING (11gR1+): Вызывает полное сканирование конвейерной табличной функции для оценки количества элементов в самом запросе перед его запуском. Это очень расточительно.
  • Расширенный Оптимизатор (Extensible Optimizer) (9i+): возможность расширения оптимизатора позволяет нам сообщить ему, что нужно поддерживать кардинальность.
  • Обратная связь по количеству элементов (Cardinality Feedback): в Oracle Database 11gR2 оптимизатор замечает, отличается ли фактическое количество элементов от ожидаемой кардинальности. Последующие запросы будут нести свою кардинальность, скорректированную на основе этой обратной связи. Если предложение выбирается из разделяемого пула или экземпляр стартует заново, эта обратная связь по количеству элементов теряется. В Oracle Database 12c обратная кардинальность по количеству элементов сохраняется в табличной области SYSAUX.

Чтобы использовать расширяемый оптимизатор, в конвейерные табличные функции нужно вручную добавить параметр, который укажет оптимизатору использовать кардинальность.

Заметим, что параметр p_cardinality нигде не используется непосредственно в функции.

Затем мы строим тип и тело типа, чтобы установить кардинальность (количество элементов) вручную. Обратите внимание на ссылку на параметр p_cardinality в типе.

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

Мы знаем, что функция возвращает 10 строк, но оптимизатор этого не знает. Независимо от числа строк, возвращенных функцией, оптимизатор использует значение параметра p_cardinality как оценку количества элементов (кардинальности).

Неявные (теневые) типы
(Implicit (Shadow) Types)

В отличие от обычных табличных функций, конвейерные табличные функции могут быть определены с использованием типов "table" и "record", определенных в спецификации пакета.

Это представляется более правильным решением, чем построение всех типов базы данных вручную, а Oracle по умолчанию строит теневые объектные типы неявно.

Как можно видеть, Oracle фактически создал три теневых объектных типа с системно сгенерированными именами для поддержки типов, требуемых конвейерной табличной функцией. По этой причине я всегда строю именованные объектные типы базы данных, вместо того, чтобы полагаться на неявные типы.

Конвейерные табличные функции, запускаемые параллельно
(Parallel Enabled Pipelined Table Functions)

Чтобы включить параллельные конвейерные табличные функции, должны быть выполнены следующие условия.

  • Должна быть включена фраза PARALLEL_ENABLE.
  • Должен присутствовать один или более входных параметров REF CURSOR.
  • Должна иметь место фраза PARTITION BY, чтобы указать метод секционирования рабочей нагрузки. Слабо связанные ref-курсоры (weakly typed ref cursors) могут использовать только фразу PARTITION BY ANY, которая определяет секционирование рабочей нагрузки случайный образом.

Основной синтаксис показан ниже.

Чтобы увидеть это в действии, сначала надо создать и населить тестовую таблицу.

Следующий пакет определяет включенные параллельные конвейерные табличные функции, которые принимают ref-курсоры по запросу из тестовой таблицы и возвращают те же самые строки вместе с SID (системный идентификатор) сессии, которая их обработала. Можно было бы использовать слабо связанный ref-курсор, подобный SYS_REFCURSOR, но тогда мы были бы ограничены только методом секционирования SYS_REFCURSOR. Следующие три функции представляют три метода секционирования.

Следующий запрос использует функцию CURSOR, чтобы преобразовать запрос к тестовой таблице в ref-курсор, который передан табличной функции в качестве параметра. Результаты группируются по SID сессий, которые обрабатывают строки. Отметим, что все строки обработаны одной и той же сессией. Почему? Потому что, хотя эта функция включена как параллельная, мы не указали ей работать параллельно.

Следующие запросы включают хинт параллельности и вызывают все эти функции.

Уровень параллелизма (DOP — degree of parallelism) может быть ниже чем тот, который указан в хинте.

Дополнительная фраза управления выходным потоком быть использована для упорядочения или кластеризации (объединение в группы) — order or cluster — данных, основанной на списке столбцов, в процессе серверной обработки. Это может быть необходимым, если существуют зависимости в данных. Например, нужно секционировать по определенному столбцу, но также и требовать, чтобы строки были обработаны в определенном порядке в рамках этого же секционирования. Расширенный синтаксис такого случая показан ниже.

Можно сделать нечто подобное:

Трансформация конвейеров
(Transformation Pipelines)

В традиционных ETL-процессах необходимо сначала загрузить данные в промежуточную область, затем сделать по ней несколько проходов, чтобы преобразовать и переместить данные в область, откуда они будут загружены в схему назначения. Прохождение данных через промежуточные таблицы может потребовать значительного количества операций дискового ввода/вывода, как для загружаемых данных, так и для данных redo-журнала. Альтернативой должно стать выполнение преобразования конвейерными табличными функциями, поскольку данные читаются из внешней таблицы и вставляются непосредственно в таблицу назначения, сокращая большую часть операций дискового ввода/вывода.

В этой секции мы увидим и проэкзаменуем с использованием обсуждавшихся ранее методов трансформацию конвейера.

Сначала в виде плоского файла нужно выкачать из файловой системы сервера базы данных какие-либо тестовые данные.

Создаем объект "directory", где указывается местоположение этого файла, создаем внешнюю таблицу, чтобы прочитать файл, и создаем таблицу назначения.

Заметим, что в таблице назначения по сравнению с внешней таблицей есть два дополнительных столбца. Каждый из этих столбцов представляет шаг преобразования. Фактические преобразования в этом примере тривиальны, но следует представить, что они могут быть сложными и невыполнимыми одним SQL-предложением. Следовательно, имеет место потребность в табличных функциях.

Пакет ниже определяет два шага процесса преобразования и процедуры для его запуска.

Вставка внутри процедуры LOAD_DATA полностью выполняет загрузку данных, включая преобразования. Предложение выглядит довольно сложно, но оно состоит из следующих простых шагов.

  • Строки запрашиваются из внешней таблицы.
  • Строки конвертируются в ref-курсор с помощью функции CURSOR.
  • Этот ref-курсор передается на первом этапе преобразования (STEP_1).
  • Возвращаемая на шаге STEP_1 коллекция запрашивается, когда используется функция TABLE.
  • Вывод этого запроса преобразуется в ref-курсор с помощью функции CURSOR.
  • Этот ref-курсор передается на второй этап преобразования (STEP_2).
  • Возвращаемая на шаге STEP_2 коллекция запрашивается, когда используется функция TABLE.
  • Этот запрос используется для выполнения вставки в результирующую таблицу.

Применяя процедуру LOAD_DATA, можно как преобразовывать, так и загружать данные.

Заметим, что этот пример не содержит процедуры обработки ошибок и что в нем нет хинтов параллельности, чтобы упростить запрос в процедуре LOAD_DATA.

Начиная с Oracle 8i, существуют так называемые "табличные функции" возвращающие набор данных, который можно рассматривать, как реляционную таблицу в предложении FROM. Проще говоря, конвейерные функции – это просто код, с которым вы можете обращаться как с таблицей базы данных. Конвейерные функции позволяют вам использовать конструкции типа SELECT * FROM <ФУНКЦИЯ_PLSQL>.

Oracle не позволит вернуть из произвольной табличной функции любой из обычных типов данных. Указанная в качестве возвращаемого типа функции коллекция должна иметь в качестве элемента табличный тип.

Создание табличной функции в Oracle ничем не отличается от создания обычной функции. Пример создания табличной функции представлен на рис.2.


Рис. 2 Пример табличной функции

Теперь функция может быть вызвана из оператора SELECT при помощи ключевого слова TABLE, сообщающего Oracle, что возвращаемую коллекцию следует интерпретировать как набор записей. Вызов через select предоставляет возможность использовать возможности простых запросов, такие как операторы group by, where и т.д. Пример вызова табличной функции представлен на рис.


Конвейеризованные табличные функции появились в 9 версии Oracle. Они являются надстройкой над табличными функциями.

Конвейеризованная табличная функция - это функция, которая возвращает результирующее множество в виде коллекции, но делает это итеративно. Другими словами, Oracle не ждет, когда выполнение функции закончится, накапливая все полученные строки в коллекции PL/ SQL, прежде чем вернуть их. Вместо этого записи по мере их готовности к включению в коллекцию возвращаются из функции.

Как и при работе с табличными функциями, при работе с конвейеризованными функциями необходимо предварительно создать табличный тип.

Между неконвейеризованной и конвейеризованной версиями имеются четыре синтаксических различия:

• Ключевое слово PIPELINED добавляется в заголовок функции с целью сообщить Oracle о необходимости возвращать результат немедленно, а не накапливать предварительно все результирующее множество.

• Команда PIPE ROW обозначает место, в котором функция возвращает отдельную запись.

• Ключевое слово RETURN осталось, но не делает ничего, осуществляя лишь выход из функции. Все результаты уже были переданы по конвейеру командой PIPE ROW.

• В предложении RETURN определить тип возвращаемых функцией данных как коллекцию (вложенную таблицу или VARRAY)

• Необходимо указывать типы SQL, а не типы PLSQL. Нужно создать типы SQL с помощью оператора create or replace type.

Конвейерные функции позволяют:

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

- распараллелить обработку строк функцией. Например, при вставке результатов вида INSERT SELECT FROM PIPELINED FUNCTION или их последующей обработке другой функцией.

- экономия используемой памяти. Вся коллекция не нужна, хватит только той части, которая будет возвращаться из функции.

- исключение NO_DATA_NEEDED позволяет корректно освободить ресурсы и завершить процесс обработки в определённых ситуациях.

Loader

SQL*Loader инструмент для загрузки данных из внешних файлов в таблицы БД ORACLE. SQL*Loader обрабатывает широкое разнообразие форматов входных файлов и дает вам возможность управлять загрузкой записей в таблицы ORACLE. SQL*Loader загружает данные в различных форматах, выполняет фильтрацию (выборочную загрузку записей в зависимости от значений данных), и может загружать несколько таблиц одновременно. Во время выполнения SQL*Loader формирует детальный файл отчета со статистикой загрузки и может также создавать файл отброшенных записей (записи, отброшенные из-за ошибок в данных) и файл пропущенных записей (записи, которые не соответствуют критерию выбора).

Утилита загрузки SQL*Loader обладает следующими возможностями:

1. Загрузки данных по сети.

2. Загрузки данных из нескольких файлов данных в течение одной операции загрузки.

3. Загрузки данных одновременно в несколько таблиц одной операцией загрузки.

4. Указания символьного набора данных.

5. Выборочной загрузки данных (можно загружать записи в зависимости от значений отдельных полей).

6. Изменять данные перед их загрузкой, используя функции SQL.

7. Генерации уникальных последовательных значений ключа в указанных столбцах.

8. Загрузки данных с диска, кассеты или именованного шлюза.

9. Генерации замысловатых отчетов об ошибках, которые могут значительно помочь в локализации ошибок.

10. Загрузки сколь угодно сложных объектно-реляционных данных.

11. Для загрузки данных типа LOB и коллекций из вспомогательных файлов данных.

Чтобы загрузить данные из внешних файлов в БД ORACLE, нужно подготовить для SQL*Loader входную информацию 2 типов: сами данные и управляющую информацию, описывающую, как выполнять загрузку. Данные, загружаемые в БД ORACLE, должны находиться в файлах на диске. Эти файлы данных SQL*Loader должны распознаваться при загрузке. Информация для этого находится в управляющем файле. Данные и управляющая информация может быть подготовлены в отдельных файлах или вместе в одном и том же файле.

Контрольный файл

Назначение этого файла – описать данные, которые должно быть загружены. Например, он описывает:

§ имена файлов данных

§ формат файлов данных

§ поля данных в этих файлах

§ как загружать данные в таблицы (какие таблицы и колонки должно быть загружены).

Некоторая информация является обязательной (где найти данные и как они соответствуют таблицам БД), однако имеется также много опций для описания и манипулирования данными. Например, инструкции могут включать указание, как форматировать или фильтровать данные, или как генерировать уникальный № ID.

Выходная информация

1. Файл отчета (log file)

2. Файл отброшенных записей (bad file)

3. Файл пропущенных данных

Порядок загрузки данных

1. Создать таблицу в которую будут загружаться данные

2. Создать файл данных в своем текущем рабочем каталоге. Данные в файле должны быть разделены. Роль разделителей могут играть любые знаки препинания. Содержимое файла может быть следующим:

"Абалхассанбейнги Араш";"Магистрант";"Факультет технологии органических веществ\Магистранты";Абалхассанбейнги Араш.bmp

3. Создать контрольный файл SQL*Loader формата ctl в своем текущем рабочем каталоге. Его можно создать в любом текстовом редакторе. Содержимое файла:

INFILE personal.txt --имя файла с данными

INTO TABLE personal --имя таблицы

REPLACE -- метод загрузки

--задается что разделителем является “;”

FIELDS TERMINATED BY ';' OPTIONALLY ENCLOSED BY '"'

( fio, jobtitle, subdn, img FILLER CHAR(100),

photo LOBFILE (img) TERMINATED BY EOF

Следует отметить, что колонки содержащие имя файла отмечены как FILLER, они не загружаются, но используются при определении LOBFILE, для определения места содержания LOB информации.

Ø INSERTМетод используемый по умолчанию. При этом предполагается, что таблица перед загрузкой пустая. Если в таблице есть строки данных, то выполнение загрузки будет прекращено.

Ø APPENDЭтот метод позволяет добавлять строки в таблицу таким образом, чтобы они не оказывали воздействия на уже существующие строки данных.

Ø REPLACE При использовании этого метода вначале удаляются все имеющиеся в таблице строки, а затем загружаются новые.

4. Из текущего рабочего каталога выполняется следующая команду SQL*Loader в приглашении командной строки

sqlldr имя_пользователя/пароль CONTROL=контрольный_файл.ctl

IMP/EXP, PUMP

Утилита экспорта exp.exe

Представляет собой исполняемый модуль, который находится в каталоге определенным переменной ORACLE_HOME.

Утилита читает базу данных, включая словарь данных, и записывает результаты в двоичный файл, который именуется как файл дампа экспорта (export dump file). В данном смысле можно экспортировать всю базу данных, конкретных пользователей (схемы) или конкретные таблицы вашей БД. В процессе экспорта, вы можете определиться есть ли необходимость экспортировать связанную с таблицами информацию словаря данных, такую как привилегии, индексы и ограничения. Созданный утилитой экспорта файл, будет содержать команды необходимые для полного восстановления всех выбранных объектов. Можно осуществлять полный (complete) экспорт всех таблиц БД, или только тех, которые были изменены, со времени последнего экспорта. Во втором случае экспорт будет инкрементальным или кумулятивным.

Инкрементальный (incremental) экспорт приведет к записи всех таблиц изменившихся со времени последнего экспорта, а кумулятивный (cumulative) - всех таблиц изменившихся со времени последнего полного экспорта. Также утилита предоставляет вам возможность сжимать свободные экстенты сильно фрагментированных сегментов данных. Например, когда какая-либо схема более менее сформировалась можно уничтожить ее табличное пространство предварительно все слив в экспорт, а далее восстановив табличное пространство импортировать данные.

Для работы с данным инструментом пользователь Oracle должен обладать привилегиями dba.

Формат исполнения команд выглядит таким образом:

exp … parameter_name = value … ,

exp – имя утилиты, parameter_name – список параметров с указанными значениями value.

Утилита импорта imp.exe

Утилита импорта тоже представляет собой исполняемый модуль, как и exp.exe. Однако применяется она для импорта данных в БД. Это означает, что imp.exe считывает двоичный дамп файл, созданный при экспорте утилитой exp, и запускает все находящиеся в нем команды на исполнение. Формат исполнения ничем не отличается от exp. Отличие заключается лишь в списке параметров.

Утилита экспорта expdp.exe

Утилита экспорта Oracle Pump позволяет экспортировать данные и метаданные в набор файлов операционной системы. Набор файлов дампа состоит из одного или нескольких файлов, содержащих табличные данные, метаданные объектов базы данных и управляющую информацию. Эти файлы записываются в специальном бинарном формате, поэтому они могут быть импортированы только impdp.exe.

Необходимо заметить, что данные утилиты являются более совершенными по сравнению с традиционными утилитами exp и imp. В поставку Oracle они входят начиная с версии Oracle Database 10gR1. К основным нововведениям можно отнести:

• Существенные архитектурные и функциональные усовершенствования.

• Поддержка внешних таблиц и предоставление PL/SQL API.

• Один поток expdp примерно в два раза быстрее exp.

• В отличие от утилит IMP и EXP, все файлы Data Pump создаются на сервере Oracle, а не на клиентской машине.

• Возможность параллельного выполнения извлечения или загрузки данных.

Так как файлы дампа записываются сервером базы данных, а не самой помпой данных (клиентом), то необходимо создать объекты с типом directory, для тех каталогов, в которые эти файлы будут записаны. Объектdirectory - это объект базы данных, который является синонимом соответствующего каталога в файловой системе сервера.

Можно также осуществлять экспорт по сети. При этом, данные из экземпляра базы данных записываются в набор файлов дампа на сервере.

Утилита импорта impdp.exe

Помпа данных импорта позваляет импортировать набор файлов дампа в целевую базу данных Oracle. Набор файлов дампа может быть импортирован в ту же самую базу данных, откуда был произведен, или в другую базу данных Oracle на другой системе. При импорте по сети, данные загружаются в целевую базу данных из базы-источника прямо по сети, минуя стадию файлов дампа. С помощью этого механизма можно запускать экспорт и импорт параллельно, минимизируя время, необходимое для всей этой операции. По сравнению с утилитой imp impdp в 15-45 раз быстрее. Нужно сказать, что данное отличие явно заметно при импорте очень большого объема данных.

JOB, SHEDULE

Это может быть и блок PL/SQL, и хранимая процедура, и внешняя процедура на C или JAVA.Частота выполнения задается или как однократное задание или регулярное.

Важное свойство пакета – задание попадает в очередь только после фиксации транзакции. То есть, если задание включено в транзакцию, а транзакция подверглась откату, то задание выполняться не будет.

Управление фоновыми заданиями реализуется отдельными серверными процессами (SNP), которые должны быть запущены, прежде чем будут активизированы задания. Эти процессы активизируются с установленной периодичностью, просматривают очередь и выполняют те задания, у которых настало время активизации. Одновременно может работать до 10 процессов SNP, которые являются неотъемлемой частью нашего экземпляра.

Поэтому сначала необходимо установить количество фоновых процессов для выполнения наших заданий.

ALTER SYSTEM SET JOB_QUEUE_PROCESSES=NN,

где NN – желаемое количество процессов (допустимо от 0 до 10).

NN зависит от интенсивности использования пакета. Если у вас много снапшотов, различных заданий, то может потребоваться увеличение NN.

Еще один параметр инициализации JOB_QUEUE_INTERVAL интервал активизации фоновых процессов в секундах. Допустимо от 1 до 3600.

Основные методы:

· DBMS_JOB.SUBMIT – создание задания

· DBMS_JOB.ISUBMIT – создание задания с указанием номера

· DBMS_JOB.INSTANCE – выбор экземпляра для выполнения

· DBMS_JOB.REMOVE – удаление задания

· DBMS_JOB.WHAT – изменение задания

· DBMS_JOB.NEXT_DATE – изменение следующей даты выполнения

Задания выполняются последовательно в соответствии с заданным временем выполнения. Если у вас один процесс обработки очереди (смотрите параметр JOB_QUEUE_PROCESSESв init.ora) , а в очереди у вас несколько заданий на одно и тоже время, то очевидно задания будут выполняться последовательно, с некоторым смещение относительно заданного времени. И к тому же очередь просматривается периодически, например 30 сек. Исходя из всего этого очевидно, что если задавать относительный момент времени (например, sysdate+1), то получим медленное смещение времени выполнения регулярного задания. Поэтому, если важно точно выполнять задание в конкретный момент времени, то используйте функцию, которая всегда возвращает фиксированный момент времени (например, trunc(sysdate)+1+2/24).

Dbms_sсhedule

К версии 11 такое устройство имевшегося планировщика заданий было сочтено слишком примитивным, и в ней появился новый планировщик, DBMS_SHEDULE ,значительно более проработанный. Он использует следующие основные понятия:

q Schedule (расписание)

q Program (программа)

q Job (плановое задание = расписание + программа)

В отличие от старого планировщика, в новом «программой» может быть не только блок PL/SQL, но и хранимая процедура на PL/SQL или на Java, внешняя процедура на С или даже команда ОС. Последнее означает, что Oracle отменяет необходимость использовать специфичные для разных платформ планировщики заданий ОС. Вдобавок, сам запуск заданий получил возможность учета текущей вычислительной обстановки в СУБД, а также желаемой приоритетности среди прочих заданий.

Расписание (Schedule)

Расписание - объект базы данных, применяемый для хранения определенного расписания выполнения заданий.

Программа (Program)

Программа - объект базы данных, хранящий определенный набор действий, который впоследствии будет сопоставлен расписанию.

DBLINK

Database Link (dblink):объект базы данных (СУБД), предназначенный для доступа к объектам базы данных, управляемой другим сервером

dblink:привилегии

Dblink: user1-user2

Dblink: shared user1-user2

Dblink: global

Секцинирвание

Секционирование – метод, позволяющий хранить сегмент данных (таблица, индекс) в виде нескольких секций, причём секции-сегменты при общности логической структуры могут иметь собственные физические атрибуты.

К секционированию предъявляют следующие требования:

Прозрачность для пользователя (пользователь приложения не должен знать, работает ли он с секционированными данными или нет)

Прозрачность для разработчика (запросы в приложении не должны специальным образом модифицироваться для работы с секционированными данными)

Удобство администрирования (секционирование данных должно не осложнять жизнь администратора базы данных, а упрощать ее)

Диапазонное секционирование

Диапазонное (range) секционирование – это секционирование, при котором для каждой секции определяется диапазон значений ключа секционирования.

Ключ секционирования в диапазонном секционировании может принимать значение даты и времени, числа или текста. Для задания диапазона используется ключевое слово less than. Используются секции небольшого, примерно равного размера.

Как-то раньше мне не приходилось сталкиваться с задачей, когда приходилось внутри одной табличной функции запрашивать данные из другой табличной функции в передавать их выше, но в конце концов этот момент настал.
Мне было необходимо перегрузить табличную функцию, а поскольку алгоритм обработки данных полностью повторял уже существующий я решил воспользоваться вызовом табличной функции.
Вроде бы всё просто, делай селект типа:
for foo in (select * from pipelined_function(x))
loop
pipe row (r.a, r.b, r.c . );
end loop;
Но мне хотелось больше удобства, не хотел я писать кучу этих имён в pipe row , и начались поиски решения. Слава богу знаний хватило на то, чтобы прийти вот к такому решению:


Создаём типы:
create or replace type tr_mixed as object (num number, str varchar2(15));
create or replace type tt_mixed is table of tr_mixed;
Создаём pipelined функцию, из которой в последствии будем получать данные:
create or replace function pipe_func(p_iter number)
return tt_mixed
pipelined
is
begin
for l_index in 1 .. p_iter
loop
pipe row (tr_mixed(l_index, 'str-' || l_index));
end loop;
end pipe_func;
А теперь создаём pipelined функцию, которая будет запрашивать данные из функции выше:
create or replace
function pipe_func_ext
return tt_mixed
pipelined
is
l_temp_tt tt_mixed;
begin
select cast(multiset (select * from table(pipe_func(10))) as tt_mixed)
into l_temp_tt
from dual;
for l_index in l_temp_tt.first .. l_temp_tt.last
loop
pipe row (l_temp_tt(l_index));
end loop;
end pipe_func_ext;
Вся магия заключается в псевдофункции MULTISET , которая используется только 4как аргумент псевдофункции CAST .Она позволяет извлечь из базы данных набор значений и тут же преобразовать его в коллекцию нужного типа. Синтаксис у неё такой:
select cast (multiset (select поле from таблица) as тип_коллекции) from dual
Если всё равно не понятно, то код:
select cast(multiset (select * from table(pipe_func(10))) as tt_mixed)

select tr_number(num, str)
bulk collect into l_temp_tt
from table(pipe_func(10));
Только весь кайф заключается в том, что с multiset , можно писать *
Проверяем, что всё работает:
select * from table(pipe_func_ext);

Читайте также: