powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Выборка из 2-х таблиц. Объединение результата в табличную функцию. Архитектура.
25 сообщений из 25, страница 1 из 1
Выборка из 2-х таблиц. Объединение результата в табличную функцию. Архитектура.
    #39597148
rtyts
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравия!
Имеется Oracle 11g . Среда разработки - SQL Developer .
Задача глобальная - переход с MySQL на ORACLE . В MySQL выборкой занимались ХП и в коде JAVA клиента разбирались полученные данные. Так как ORACLE в плане мультиселекта с помощью ХП не канает, пришло решение делать функции, которые возвращают таблички и потом в клиенте банально SELECT * FROM TABLE(ф-ия) .

Теперь задача усложнилась. Надо параллельно взять данные из 2-х таблиц, над частью данных "на лету" выполнить мат. операции и также всё выдать функцией с возвратом таблицы.
Код для теста:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
CREATE TABLE HISTORIAN 
(
  ID NUMBER NOT NULL 
, ITEM_ID NUMBER NOT NULL 
, EVENT_TS DATE DEFAULT SYSDATE 
, value NUMBER 
);

INSERT INTO historian (id,item_id,value) VALUES (1,100, 32);
INSERT INTO historian (id,item_id,value) VALUES (2,100, 18);
INSERT INTO historian (id,item_id,value) VALUES (3,200, 5);
INSERT INTO historian (id,item_id,value) VALUES (4,200, 7);

CREATE TABLE ITEM 
(
  ID NUMBER NOT NULL 
, NAME VARCHAR2(20) NOT NULL 
);
INSERT INTO item (id,name) VALUES (100,'name100');
INSERT INTO item (id,name) VALUES (200,'name200');

create or replace TYPE myGlobType IS OBJECT(
    l_id NUMBER,
    l_name VARCHAR(20),
    value NUMBER     
  );
create or replace TYPE myGlobTable IS TABLE OF myGlobType;



Теперь функция (реально она в пакете и математика над value сложнее и полей этих больше, чем одно):
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
CREATE OR REPLACE FUNCTION MYFUNCTION RETURN myGlobTable AS 
  l_tbl_res myGlobTable:=myGlobTable();
  value_OUT NUMBER;
  
  CURSOR crs IS
  SELECT * FROM ITEM;
  l_row crs%ROWTYPE;
  
  BEGIN
   OPEN crs;
LOOP
FETCH crs INTO l_row;
EXIT WHEN crs%NOTFOUND;
SELECT SUM(value) into value_OUT FROM historian where historian.ITEM_ID=l_row.ID;
l_tbl_res.EXTEND;
l_tbl_res(l_tbl_res.LAST):=myGlobType
(l_row.id,
l_row.name,
value_OUT);
END LOOP;
CLOSE crs;
    RETURN l_tbl_res;
END MYFUNCTION;



Результат:
Код: plsql
1.
SELECT * FROM TABLE(MYFUNCTION());


автор100 name100 50
200 name200 12

Вопросы:
1. решение совсем плохое? если да, то чем.
2. в Types может только ...IS OBJECT... создавать, верно?
3. в ...IS OBJECT... , которые в глобальных Types, только явное указание типа поля? %TYPE не работает, верно?
4. Ф-ия MYFUNCTION может работать только с TABLE s, которые объявлены в глобальных Types?
5. Подскажите более хорошее решение, хотя бы в общих чертах.

Заранее спасибо!
...
Рейтинг: 0 / 0
Выборка из 2-х таблиц. Объединение результата в табличную функцию. Архитектура.
    #39597170
rtyts,

не надо ходить со своими уставами в чужой монастырь. раз уж переходишь на оракл, то и делай всё так, как принято "бест практиками" в оракле... Зачем прикручивать кривой велосипед в телегу пятым колесом?
...
Рейтинг: 0 / 0
Выборка из 2-х таблиц. Объединение результата в табличную функцию. Архитектура.
    #39597198
Загги
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый Э - Эхrtyts,
не надо ходить со своими уставами в чужой монастырь. раз уж переходишь на оракл, то и делай всё так, как принято "бест практиками" в оракле... Зачем прикручивать кривой велосипед в телегу пятым колесом?
Есть такой раздел в документации "Лучшие практики"? Или собирать инфу в блогах типа "Спроси у Тома"?
...
Рейтинг: 0 / 0
Выборка из 2-х таблиц. Объединение результата в табличную функцию. Архитектура.
    #39597201
Загги,

для начала - руководствоваться здравым смыслом.
если не нашлось средства безболезненно реализовать свою хотелку, стОть задуматься - "а всё ли правильно я делаю"?
потому как проктологическая стоматология - вещь, конечно, занимательная, но крайне неприятная и, зачастую, неэффективная...
...
Рейтинг: 0 / 0
Выборка из 2-х таблиц. Объединение результата в табличную функцию. Архитектура.
    #39597202
Добрый Э - ЭхЗагги,

для начала - руководствоваться здравым смыслом.
если не нашлось средства безболезненно реализовать свою хотелку, стОит задуматься - "а всё ли правильно я делаю"?
потому как проктологическая стоматология - вещь, конечно, занимательная, но крайне неприятная и, зачастую, неэффективная...
...
Рейтинг: 0 / 0
Выборка из 2-х таблиц. Объединение результата в табличную функцию. Архитектура.
    #39597216
Загги
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый Э - ЭхЗагги,
для начала - руководствоваться здравым смыслом.
если не нашлось средства безболезненно реализовать свою хотелку, стОть задуматься - "а всё ли правильно я делаю"?
потому как проктологическая стоматология - вещь, конечно, занимательная, но крайне неприятная и, зачастую, неэффективная...
А вообще, по архитектурным решениям какую литературу почитать?
...
Рейтинг: 0 / 0
Выборка из 2-х таблиц. Объединение результата в табличную функцию. Архитектура.
    #39597254
hck1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Используй global temporary table ... on commit delete rows. В процедуре заполнишь, клиент вычитывает. Еще почитай о ref_cursor, одна процедура может вернуть несколько рефкурсоров
...
Рейтинг: 0 / 0
Выборка из 2-х таблиц. Объединение результата в табличную функцию. Архитектура.
    #39597266
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да вопрос и проблемы автора вообще не понятны простым смертным

"...Задача глобальная - переход с MySQL на ORACLE. В MySQL выборкой занимались ХП и в коде JAVA клиента разбирались полученные данные. Так как ORACLE в плане мультиселекта с помощью ХП не канает..."

Есть ref cursor'ы. Есть Pipe Line ф-ции. Есть временные таблицы. Т.ч. чем у автора топика "Oracle не канает", совершенно не понятно

__Самоцель__ все оборачивать в ХП, мне никогда понятна не была. Результат только один, еще больше кода, еще больше бардака (т.к. часто он прямо пропорционален кол-ву кода)

Если же ХП возвращает массив, совершенно не понятно, зачем на клиенте оборачивать все в SELECT. Прямо на Java массив и вычитывайте, хотя там свои сложности будут, но потенциально возможности вроде есть (объектные типы редко в продакшене использовал).

Ну а пока взяли СУБД и пытаются ее переделать в "массивы" и "текстовые файлы". Поверх еще объекты и XML натянуть... и совсем красота будет...

IMHO & AFAIK
...
Рейтинг: 0 / 0
Выборка из 2-х таблиц. Объединение результата в табличную функцию. Архитектура.
    #39597286
rtyts
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
раз уж переходишь на оракл, то и делай всё так, как принято
так а как принято? об этом и вопрос. я сделал так, как вычитал у Фейерштейна. Он пишет, TABLE() - это хорошо и правильно.
Используй global temporary table
а вот это как раз таки не рекомендуют.
ref_cursor
это я тоже попробовал. просто не знаю, что лучше через ref_cursor или через TABLE()

Добрый Э - Эх , вы можете посоветовать верное, "не телега с 5-ым колесом", решение? В общих чертах хотя бы.
...
Рейтинг: 0 / 0
Выборка из 2-х таблиц. Объединение результата в табличную функцию. Архитектура.
    #39597296
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rtytsэто я тоже попробовал. просто не знаю, что лучше через ref_cursor или через [b]TABLE()
VIEW !!!
...
Рейтинг: 0 / 0
Выборка из 2-х таблиц. Объединение результата в табличную функцию. Архитектура.
    #39597301
rtyts
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid KudryavtsevТ.ч. чем у автора топика "Oracle не канает"
"не канает" имелось ввиду, что нереализуемо также, как в MySQL или MS SQL S.

Запрос с параметрами, а значит нужны переменные, а значит надо использовать PL/SQL. B если в MySQL была ХП с параметрами IN, а на выходе был multirow рекордсет, то в оракл это не канает.

Leonid Kudryavtsev__Самоцель__ все оборачивать в ХП, мне никогда понятна не была.
Чес говоря я вообще не задавался этим вопросом, так как так было удобно делать в MySQL или MS SQL S, на клиентах понятный и минимальный код. Но самое главное - на 4-х проектах у меня это было бизнес-правило Заказчика. То есть так требовал Заказчик - всё через ХП. Ну мы, я, так и делали. И было это красиво на MySQL или MS SQL S.
Я не буду устраивать холивар на эти темы. Ветка oracle тут процентов на 30 забита именно этим. Я согласен, оракл другой и подход иной.
Просто дайте совет, как реализовать вышеуказанную задачу более правильно. Я ораклом занимаюсь 3-ю неделю, опыта нет. Мне нужен совет, а не констатация факта, что я "ламмер" и делаю через *опу, это я и так понимаю.
...
Рейтинг: 0 / 0
Выборка из 2-х таблиц. Объединение результата в табличную функцию. Архитектура.
    #39597304
rtyts
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid Kudryavtsevrtytsэто я тоже попробовал. просто не знаю, что лучше через ref_cursor или через [b]TABLE()
VIEW !!!
пример кода не напишите? выходит так, что нужна вьюха с входными параметрами и if-ами внутри. это возможно в оракл/sql developer-е?
...
Рейтинг: 0 / 0
Выборка из 2-х таблиц. Объединение результата в табличную функцию. Архитектура.
    #39597307
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IMHO
вместо всех типов и вообще всей хреномунтии, раз уж так хотите логику инкапсулировать на сервере, используйте view
Код: sql
1.
2.
3.
4.
5.
6.
7.
create view myView as
select
  item.id as  l_id, item.name as l_name, SUM(historian.value) as value
  from item, historian 
  where item.id = historian.item_id
group by
  item.id;


ну и на клиенте
Код: sql
1.
select * from myView


IMHO & AFAIK
...
Рейтинг: 0 / 0
Выборка из 2-х таблиц. Объединение результата в табличную функцию. Архитектура.
    #39597326
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rtytsB если в MySQL была ХП с параметрами IN, а на выходе был multirow рекордсет
IMHO наиболее похожая возможно Oracle: Ref cursor

rtytsif-ами внутри. это возможно
Да, без проблем:

Where clause
конструкция CASE
ф-ция DECODE
union
etc...

rtytsвьюха с входными параметрами
Стандартно такое не возможно.

Но требуется КРАЙНЕ редка и часто по причине борьбы с оптимизатором и битвы с производительностью.

Обычно такое желание возникает про построении сложных отчетов. Если отчет сложен и его не удобно/быстро делать Select'ом, то на мой взгляд самое просто: временная таблица + код в Before report + select из временной таблицы

Если надо в online, то можно передать "параметры" через глобальную переменную "внутрь" запроса. Или контекст (нужно искать по форуму) или просто глобальная переменная в пакете и ф-ция, которая это значение возвращает.

Это НЕ бест практис, скорее затычки для СЛОЖНЫХ случаев. В 99% случаев. ничего этого не требуется.

Note: хотя я бы сложные отчеты на временных табличках скорее отнес к бест практису, т.к. иначе отчеты часто переусложняют. Пусть лучше будут лишние таблички, но будет простой, понятный код и быстро работающие отчеты IMHO
...
Рейтинг: 0 / 0
Выборка из 2-х таблиц. Объединение результата в табличную функцию. Архитектура.
    #39597333
Leonid Kudryavtsev,

при "рефакторинге" сложных "отчетных" запросов можно и WITH использовать для декомпозиции запроса на более понятные составляющие. А если нужна будет материализация до уровня временной таблицы какой-то из "простых" частей - сервер и сам это сделает...
...
Рейтинг: 0 / 0
Выборка из 2-х таблиц. Объединение результата в табличную функцию. Архитектура.
    #39597342
rtyts
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid Kudryavtsev , Спасибо! Буду копать по указанным направлениям. Моя ошибка, что упростил функцию сильно вначале.

Если не затруднит, то по этим вопросам, ну чтобы быть уверенным мне в дальнейшем:

автор2. в Types может только ...IS OBJECT... создавать, верно?
3. в ...IS OBJECT..., которые в глобальных Types, только явное указание типа поля? %TYPE не работает, верно?
4. Ф-ия MYFUNCTION может работать только с TABLEs, которые объявлены в глобальных Types?


Ещё раз спасибо!
...
Рейтинг: 0 / 0
Выборка из 2-х таблиц. Объединение результата в табличную функцию. Архитектура.
    #39597348
rtyts
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый Э - Эх , я вот кстати хотел уйти от SQLя. От join-ов и СТЕ...
Хотел именно как-бы так сугубо и жёстко по PL/SQL-вски, раз уж взялся за него.

Да, там сложный онлайн отчёт из исторической базы. Выборка и по датам, и по группам устройств, и типу события...там порядка 20 колонок в этой табличке. Изменять структуру таблиц не разрешено.
...
Рейтинг: 0 / 0
Выборка из 2-х таблиц. Объединение результата в табличную функцию. Архитектура.
    #39597361
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
OFFTOPIC ON

А если нужна будет материализация до уровня временной таблицы какой-то из "простых" частей - сервер и сам это сделает...

можно то можно... но больно сложно получается. Я как-то не любитель 10-20 страничных селектов по 30-60 и более килобайт ))). А с учетом, что отчеты делают отдельно выделенные люди и им это еще нужно объяснить...

Ну и часто нужно переиспользовнаие данных в разных местах/разделах отчета

Т.ч. временные таблички + before report как-то и проще, и удобнее "обычному разработчику отчетов" ( ( C ) тайд ), и быстрее для сервера => меньше ошибок и больше "удовлетворенность" конечного пользователя. Для сложных случаев. В остальных случаях: обязательные view (несколько!) на сервере + простейшие select * в отчете

IMHO & AFAIK

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

А вот тут и возникает желание "пропихнуть параметры" во View (((

Как минимум "дата на которую строим отчет" (наличие истории), "периоды дат, за которые отбираем данные" и так далее...

Действительно не удобно, что во View нельзя параметры передавать и потом в тексте View использовать как константы IMHO
...
Рейтинг: 0 / 0
Выборка из 2-х таблиц. Объединение результата в табличную функцию. Архитектура.
    #39597363
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
автор2. в Types может только ...IS OBJECT... создавать, верно?
3. в ...IS OBJECT..., которые в глобальных Types, только явное указание типа поля? %TYPE не работает, верно?
4. Ф-ия MYFUNCTION может работать только с TABLEs, которые объявлены в глобальных Types?
2+3 - редко использую, т.ч. затрудняюсь ответить
4.
Для ф-ции - все равно: можно и глобальные, можно и локальные в пакете.
Для SELECT - только глобальные
...
Рейтинг: 0 / 0
Выборка из 2-х таблиц. Объединение результата в табличную функцию. Архитектура.
    #39597368
hck1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rtytsраз уж переходишь на оракл, то и делай всё так, как принято
так а как принято? об этом и вопрос. я сделал так, как вычитал у Фейерштейна. Он пишет, TABLE() - это хорошо и правильно.
Используй global temporary table
а вот это как раз таки не рекомендуют.

глупости. читай еще раз. TABLE() поверх массивов торчит в памяти и убивает оптимизатор. такой изврат имеет смысл лишь в некотором круге задач, где гарантирован небольшой объем массива. стандартный подход в оракле, то что черезчур сложно запихнуть в декларативный вью - пихаем в global temporary table
...
Рейтинг: 0 / 0
Выборка из 2-х таблиц. Объединение результата в табличную функцию. Архитектура.
    #39597384
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Передача параметров во View (вроде есть пример с контекстом)
https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:9536277800346269502

Передача параметров во View через пакет + холевар (но это не бест-практис, вроде лучше через контекст)
http://www.sql.ru/forum/910885/hochu-podelitsya-parametrizovannoe-view-s-pomoshhu-paketa?hl=????????? view ????????

Нормального примера с контекстом на форуме не нашел, больно много в результате тем вылазит (((
...
Рейтинг: 0 / 0
Выборка из 2-х таблиц. Объединение результата в табличную функцию. Архитектура.
    #39597400
global variables
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Leonid Kudryavtsev...

Действительно не удобно, что во View нельзя параметры передавать и потом в тексте View использовать как константы IMHO
А разве пакетные переменные кто-то отменил?
...
Рейтинг: 0 / 0
Выборка из 2-х таблиц. Объединение результата в табличную функцию. Архитектура.
    #39597482
фотошоп
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Дайте уже страдальцу ссылку на труд фотошопа - пусть ознакомится "как можно" и "как не нужно"
...
Рейтинг: 0 / 0
Выборка из 2-х таблиц. Объединение результата в табличную функцию. Архитектура.
    #39597486
Фотография Amberit
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторПередача параметров во View
Параметризованная VIEW хорошо получается с использованием CLIENTCONTEXT и при соблюдении некоторых соглашений по именованию аттрибутов контекста.
И как мне кажется, REFCURSOR-ы для задачи ТС - самое то.

А если стоит цель изменить БД, но не переписывать Application-часть - так это утопия. Все равно в итоге придется править везде.
...
Рейтинг: 0 / 0
Выборка из 2-х таблиц. Объединение результата в табличную функцию. Архитектура.
    #39597657
Sheldon Cooper
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rtyts...
Задача глобальная - переход с MySQL на ORACLE . В MySQL выборкой занимались ХП и в коде JAVA клиента разбирались полученные данные.
...
Вопросы:

5. Подскажите более хорошее решение, хотя бы в общих чертах.

Заранее спасибо!
не благодари

rtytsLeonid KudryavtsevТ.ч. чем у автора топика "Oracle не канает"
"не канает" имелось ввиду, что нереализуемо также, как в MySQL или MS SQL S.

Запрос с параметрами, а значит нужны переменные, а значит надо использовать PL/SQL. B если в MySQL была ХП с параметрами IN, а на выходе был multirow рекордсет, то в оракл это не канает.

Leonid Kudryavtsev__Самоцель__ все оборачивать в ХП, мне никогда понятна не была.
Чес говоря я вообще не задавался этим вопросом, так как так было удобно делать в MySQL или MS SQL S, на клиентах понятный и минимальный код. Но самое главное - на 4-х проектах у меня это было бизнес-правило Заказчика. То есть так требовал Заказчик - всё через ХП. Ну мы, я, так и делали. И было это красиво на MySQL или MS SQL S.
Я не буду устраивать холивар на эти темы. Ветка oracle тут процентов на 30 забита именно этим. Я согласен, оракл другой и подход иной.
Просто дайте совет, как реализовать вышеуказанную задачу более правильно. Я ораклом занимаюсь 3-ю неделю, опыта нет. Мне нужен совет, а не констатация факта, что я "ламмер" и делаю через *опу, это я и так понимаю.

Глобальная задача превращается в локальную
Пусть не без греха решение , зато портировали на оркалий, в резюме дополнительная галка...

[youtube=
YouTube Video
...
Рейтинг: 0 / 0
25 сообщений из 25, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Выборка из 2-х таблиц. Объединение результата в табличную функцию. Архитектура.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]