У меня есть пакет, который я использую для создания некоторых таблиц на основе данных из других таблиц. В конце этого пакета я запрашиваю необходимую мне информацию через уже созданные представления. Однако у меня есть куча представлений, и я хотел бы, чтобы они были в порядке где-то в этом пакете или в том, что имеет отношение к этому пакету. Каким был бы способ добиться этого?
Если вы хотите сохранить их «где-то в пакете», то это будет комментарий, который вы должны написать самостоятельно и позаботиться о его поддержке.
Другой — назовем его «динамическим» — запрашивать user_dependencies
в любое время. Вот пример:
Это вид:
SQL> create view v_emps as
2 select d.dname, e.ename, e.job
3 from emp e join dept d on e.deptno = d.deptno;
View created.
Пакет, который выполняет что-нибудь с представлением:
SQL> create or replace package pkg_test
2 as
3 procedure p_test;
4 end;
5 /
Package created.
SQL> create or replace package body pkg_test
2 as
3 procedure p_test is
4 l_cnt number;
5 begin
6 select count(*)
7 into l_cnt
8 from v_emps;
9 end;
10 end;
11 /
Package body created.
Запрос user_dependencies
:
SQL> select name, referenced_name, referenced_type
2 from user_dependencies
3 where name = 'PKG_TEST'
4 and referenced_owner = 'SCOTT';
NAME REFERENCED_NAME REFERENCED_TYPE
------------------------------ -------------------- ------------------
PKG_TEST PKG_TEST PACKAGE
PKG_TEST V_EMPS VIEW
SQL>
Если вы хотите ограничить его только представлениями, добавьте еще одно условие (это будет строка № 5 в запросе):
and referenced_type = 'VIEW'
Представления и пакеты являются атомарными объектами Oracle и не могут быть созданы внутри каждого из них. Другие.
Однако Oracle предлагает другую структуру "представления" только для PL/SQL - конвейерную функцию. Это может оказаться полезным, если в вашем случае важна группировка «представлений».
Вы можете создать множество конвейерных функций в одном пакете, каждая из которых концептуально создает свое «представление». На конвейерную функцию можно сослаться в обычном операторе select, заключив его в оператор table(), как показано в примере ниже.
Для иллюстрации я создал очень простой пакет под названием «представления», который содержит одну конвейерную функцию «клиенты», которая возвращает идентификаторы и имена клиентов из таблицы клиентов. Я мог бы, конечно, включить другие конвейерные функции в мой групповой пакет «представления», например. «счета», «продажи» и т. д. и т. д. (эти функции также могут принимать параметры, как и любая обычная функция пакета, если это необходимо)
Вот простая иллюстрация:
А. создайте спецификацию пакета для вашей конвейерной таблицы «представление клиента»
create or replace package views as
type t_cust_rec is record(id customer.id%type
,name customer.name%type
);
type t_cust_cur is ref cursor return t_cust_rec;
type t_cust_tab is table of t_cust_rec;
function customers
return t_cust_tab pipelined;
function sales ....;
function invoices ...;
end views;
B. создайте тело пакета для вашей конвейерной таблицы «представление клиента»
create or replace package body views as
function customers
return t_cust_tab pipelined
is
sRows t_cust_cur;
rRow t_cust_tab;
begin
open sRows for
select id
,name
from customer;
loop
fetch sRows into rRow;
exit when sRows%notfound;
pipe row (rRow);
end loop;
end;
function sales ....
function invoices ...
end views;
C. используйте свою конвейерную табличную функцию в обычном операторе выбора
select *
from table(views.customers)
where name like 'Bob%';
select *
from table(views.sales)
where amount > 10000.00;
select sum(total)
from table(views.invoices);
Примечание: начиная с Oracle 12.2 (если я правильно помню) table
является необязательным, и в предыдущих выпусках вам приходилось объявлять тип схемы (не локальный тип пакета), чтобы использовать конвейерную функцию в чистом контексте SQL. А с 18c есть макросы SQL и полиморфные табличные функции, которые имеют очень низкие накладные расходы на разработку (например, ручное перепечатывание всех столбцов представления в типе record
)
Представления и таблицы являются объектами схемы. Обычно они создаются один раз и живут вечно. Если вы используете их в своем пакете, вы можете найти эти отношения через системное представление
dba_dependencies
. Но если вы хотите связать их с пакетом, лучше сделать это во внешнем инструменте (откуда вы запускаетеcreate package
).