[Oracle SQL] типа таблица от параметра

Teteshnik

Не знал как еще назвать пост. Ну да ладно.
Вобщем.
Есть у нас таблица people.
Для каждого человека нужно высчитать кучи инф-ии по базе. Совершенно различной. Пол, вес, цвет волос, средний пол за период, наихудший цвет волос за период. Не суть что. Используется много PL/SQL кода.
Все эти данные приходится использовать в сотнях отчетов.
Мне нужен объект БД, который зависел бы от параметра, т.е. id человека. При вызове которого в языке SQL, я мог бы его присоединить как таблицу по ID и выбрать все нужные поля из этого объекта. А в объекте собственно поля и есть - то что мне нужно было посчитать по базе.
select
worse_hair_colour,
agv_weight
from OBJECT(ID)
Либо как курсор
select
OBJECT(ID).worse_hair_colour,
OBJECT(ID).agv_weight
from people
Сейчас реализовано как type + функция как оболочка этого типа.
в итоге немного туповато выглядит при вызове. т.е. в ф-ю нужно передать параметр, который я хочу достать из type. т.е.
person_params(ID,'worse_hair_colour')
Подскажите плиз чего-нить, ато еще весь SELECT manual не асилил :)

ava3443

по-моему нужен просто view?
если хочется именно чтобы была функция, которая возвращает таблицу - есть "pipelined table function"

Teteshnik

ну, понимаешь, во-первых это долго считаться будет.
оптимизировать нужно будет здорово все это.
но главное, что считается там все не a + b, а считается с помощью PL/SQL, что с вьюхой никак не сделаешь.

kill-still

долго считаться будет
возможно сейчас меня закидают помидорами, но есть materialized view.
ещё можно сделать таблицу заполняемую раз в N времени, или по триггерам.
а считается с помощью PL/SQL, что с вьюхой никак не сделаешь.
в оракле в скулёвых запросах можно использовать хранимки. гугли по "конвейерные функции".

Vantucha

pipelined function

Teteshnik

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

Teteshnik

pipelined function
епт, чо-то интересное. буду читать. всем спс.

kill-still

Тогда не парься и пиши въюху. Оно весьма шустро работает, если правильно оптимизировано.

Teteshnik

почему не понял?
я ж говорю, для подсчета величин нужен pl/sql код.

kill-still

всё что можно переводи в скуль. что нельзя(или не хватает опыта перевести на скуль) - то пиши конвейерными хранимками. хотя на оракловом скуле всё что хочешь можно посчитать - вопрос только в производительности.
З.Ы. и да, не оптимизируй ничего "на глазок". только профилировщиком. или хотя бы план/стоимость запроса смотри на базе. только не на тестовой, а на рабочей.

Teteshnik

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

Dasar

сделай функции, а потом их "спрячь" во вью, а в конечном запросе используй уже вьюху

kill-still

В не надо такие простыни писать. :grin: :grin:
разбивай и декомпозируй.

Teteshnik

ладно, ф-ии еще и не от одного параметра. время, и т.д.
вьюха нихера себе получается.

dava

парировать пока нечем. единственный аргумент - кода очень много. править его в одномочень большом селекте очень сложно будет. хочется более-менее структурированный объект.
врубиться в этот селект новому человеку будет сложно. тут как бы простоту и читаемость нужно учитывать.
для этого есть with
в идеале нужно всё загнать в sql, разбив на блоки with, в которых ты будешь фильтровать и обогащать информацию; они будут последовательны, их просто читать и документировать, не то что inline-views
дополнительный плюс with - можно материализовывать отдельные блоки через materialize, что зачастую положительно сказывается на производительности, минус тут будет в отсутствии индексации, так что делать это нужно аккуратно - только когда в блоке сравнительно мало (<1000) строк, и его получается выгоднее джойнить хэшем в любом случае

dava

Вообще в формулировке задачи скрыт какой-то подвох: ты говоришь, что хочешь считать информацию по одному человеку (чётко по id). Объём выборки в данном случае большим быть не может, если конечно ты не селектишь его координаты каждую секунду. При этом ты говоришь, что база оперативная, и грузить её даже materialized view не стоит. Если база оперативная, то с индексацией есть некоторые траблы, я правильно понимаю? Значит, при выборке по одному челу, с большой вероятностью ты цепляешь часть таблиц фулл сканом?
Не лучше ли создать хранилище данных, отделённое от оперативной базы, которое ты обвешаешь индексами и сможешь мгновенно вытягивать всю необходимую инфу запросом с минимальным костом?

kill-still

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

dava

1. Чтоб материалайзить, выигрывая в скорости.
2. Чтоб сделать единый запрос читаемым, как книгу.
Что он для другого предназначен спорить не буду, но здесь он может пригодиться, если важен последующий рефакторинг.
Мелкие вьюхи на каждый блок имеют смысл, на мой взгляд, если их мало. Если их куча, то будет неудобно, да и повторное использование обычно бывает не масштабным и в рамках одной задачи. Логичнее уж тогда использовать мелкие матвьюхи с query rewrite, но и там код всё равно будет заново руками набираться, просто работать станет быстрее.

Teteshnik

подвох в том, что хочу увидеть больше вариантов.
with не подойдет, потому что.... внимание!....есть приложение, в котором также планируется использование этого мега объекта. Приложение для одной из своих задач хавает только SQL и, барабанная дробь, with не хавает.

kill-still

ты сам-то понял, что сказал? :)

dava

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

Teteshnik

да, не понял от чем сначала. это понятно.
Оставить комментарий
Имя или ник:
Комментарий: