powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Список в запрос с клиента (почти списки в вьюхи :) )
13 сообщений из 13, страница 1 из 1
Список в запрос с клиента (почти списки в вьюхи :) )
    #39387371
Фотография barrabas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть БД Ora11.2.
Приложению (веб-сервис на dotNET) требуется делать запросы к БД получая информацию для тысяч карт, на вход поступают запросы со списком номеров карт (от 1 до 10000), для каждой карты нужно выбрать требующуюся инфу и вернуть общим датасетом.
БД - сторонняя система (порядка 80 БД с одинаковой структурой), добавлять пакеты, вьюхи нельзя (точнее можно в отдельную схему, под которой идет соединение, но так как баз более 80 и схемы с данными имеют разные названия, то поддержка такого кода очень геморная, он есть но плодить его, без надобности, нет желания).

Сейчас сделано так:
веб-сервис получив массив номеров карт (10 знаков в номере), генерирует массив с XML по 2000символов примерно
Код: plaintext
1.
2.
xml[0] = "<cards><c num='0000000001' /><c num='0000000005' />...</cards>" 
xml[1] = "<cards><c num='0000000086' /><c num='0000000147' />...</cards>" 
xml[n] = "<cards><c num='00000xxxxx' /><c num='00000sssss' />...</cards>" 
т.е. помещается примерно по 90 карт в порцию, если прилетело 9000 карт нужно сделать 100 порций

воздаёт OracleCommand с текстом
Код: plsql
1.
2.
3.
4.
5.
6.
                select i.*
                  from XXX.CARD_INFO i,
                       (select to_number(extractValue(COLUMN_VALUE,'C/@NUM'))  CARD_NUM
                           from table(xmlsequence(xmltype(:cardsXML).extract('//C')))
                        ) p 
                 where i.CARD_NUM =  p.CARD_NUM



и в цикле выполняет запросы (можно конечно в разных потоках, но запросов на сервис и так много)
разумеется создание команды и открытие соединение вынесено за цикл, в цикле только присвоение значение параметра и фетч курсора.
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
            // Первая порция            
            c.Parameters.Add("cardsXML", OracleDbType.VarChar, 4000).Value = cardsXMLs[0];
            var result = c.FillToNewDataTable();
            // Остальные если нужно
            for (int i = 1; i < cardsXMLs.Count; i++)
            {
               c.Parameters["cardsXML"].Value = cardsXMLs[i];
               result.Load(c.ExecuteReader());
            }




Я посмотрел на это дело и решил попробовать биндить сразу параметр с типом XML, по сути это CLOB я думаю.
Измелил SQL
Код: plsql
1.
2.
3.
4.
5.
6.
 select i.*
                  from XXX.CARD_INFO i,
                       (select to_number(extractValue(COLUMN_VALUE,'C/@NUM'))  CARD_NUM
                           from table(xmlsequence(:cardsXML.extract('//C')))
                        ) p 
                 where i.CARD_NUM =  p.CARD_NUM


Стал генерировать один большой XML
Код: c#
1.
c.Parameters.Add("cardsXML", OracleDbType.Xml).Value = new OracleXml(xmlText);


Работаь то работает и даже немного быстрее (для 10000 карт полторы минуты (запрос намного сложнее чем в примере), а было 2 минуты).

но меня не покидает мысль что нагрузка на БД станет больше, на создание временных CLOB или я гоню?

Какие еще варианты?
Создать ОN COMMIT DELETE ROWS таблицу в своей схеме и наполнять ее перед запросом.
Создать пакет с переменной-массивом и pipe line функцией у себя, но сервис испольует пул соединений, не получит ли сессия не свой набор данных? или использовать словарь массивов с ключем, но боюсь если будут обрывы выполнений и запрос за собой не почистит, то данные будут копиться, т.к. хз когда пул реально сессию закроет (или опять гоню?)
...
Рейтинг: 0 / 0
Список в запрос с клиента (почти списки в вьюхи :) )
    #39387378
Фотография AmKad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
barrabas
Код: plsql
1.
2.
3.
4.
5.
6.
                select i.*
                  from XXX.CARD_INFO i,
                       (select to_number(extractValue(COLUMN_VALUE,'C/@NUM'))  CARD_NUM
                           from table(xmlsequence(xmltype(:cardsXML).extract('//C')))
                        ) p 
                 where i.CARD_NUM =  p.CARD_NUM

Попробуй поиграться одним xmltable вместо extractValue поверх xmlsequence.
barrabasКакие еще варианты?Я бы попробовал еще вариант с передачей в качестве параметра коллекции.
Варианты с pipelined функцией и temporary table даже не рассматривал бы.
...
Рейтинг: 0 / 0
Список в запрос с клиента (почти списки в вьюхи :) )
    #39387379
Фотография barrabas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AmKadbarrabas
Код: plsql
1.
2.
3.
4.
5.
6.
                select i.*
                  from XXX.CARD_INFO i,
                       (select to_number(extractValue(COLUMN_VALUE,'C/@NUM'))  CARD_NUM
                           from table(xmlsequence(xmltype(:cardsXML).extract('//C')))
                        ) p 
                 where i.CARD_NUM =  p.CARD_NUM

Попробуй поиграться одним xmltable вместо extractValue поверх xmlsequence.
barrabasКакие еще варианты?Я бы попробовал еще вариант с передачей в качестве параметра коллекции.
Варианты с pipelined функцией и temporary table даже не рассматривал бы.
т.е. создать в своей схеме объектный тип
Код: plsql
1.
create or replace type NumberTable is table of number;



попытаться его забиндить в него массив сразу через провайдер?

вроде такие примеры в доке встречал.
...
Рейтинг: 0 / 0
Список в запрос с клиента (почти списки в вьюхи :) )
    #39387386
Фотография AmKad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
barrabasт.е. создать в своей схеме объектный тип
Код: plsql
1.
create or replace type NumberTable is table of number;

попытаться его забиндить в него массив сразу через провайдер?
Да, только насколько мне кажется номера карт у тебя строковые. Если тип нужно шарить между схемами, то можно создать public-синоним и выдать права другим схемам public-у.
...
Рейтинг: 0 / 0
Список в запрос с клиента (почти списки в вьюхи :) )
    #39387387
Фотография barrabas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AmKadbarrabasт.е. создать в своей схеме объектный тип
Код: plsql
1.
create or replace type NumberTable is table of number;

попытаться его забиндить в него массив сразу через провайдер?
Да, только насколько мне кажется номера карт у тебя строковые. Если тип нужно шарить между схемами, то можно создать public-синоним и выдать права другим схемам public-у.
это пример просто
в БД номер число
...
Рейтинг: 0 / 0
Список в запрос с клиента (почти списки в вьюхи :) )
    #39387388
Фотография barrabas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Попробовать стоит.
Проблема в том, что создать объект нужно будет рассылать скрипт в другие подразделения, а они не очень выполнять скрипты на десятках БД :)
...
Рейтинг: 0 / 0
Список в запрос с клиента (почти списки в вьюхи :) )
    #39387396
Фотография AmKad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И еще, .NET-овская (ORM-)гляделка может по дефолту не увидеть тип, если он доступен посредством синонима на объект в другой схеме.

barrabasПопробовать стоит.
Проблема в том, что создать объект нужно будет рассылать скрипт в другие подразделения, а они не очень выполнять скрипты на десятках БД :)Стандартного типа тебе хватит? Как минимум, в 11-ой версии он должен быть везде.
Код: plsql
1.
2.
CREATE OR REPLACE TYPE SYS.ODCINumberList AS VARRAY(32767) of NUMBER
/
...
Рейтинг: 0 / 0
Список в запрос с клиента (почти списки в вьюхи :) )
    #39387407
Фотография barrabas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AmKadИ еще, .NET-овская (ORM-)гляделка может по дефолту не увидеть тип, если он доступен посредством синонима на объект в другой схеме.

barrabasПопробовать стоит.
Проблема в том, что создать объект нужно будет рассылать скрипт в другие подразделения, а они не очень выполнять скрипты на десятках БД :)Стандартного типа тебе хватит? Как минимум, в 11-ой версии он должен быть везде.
Код: plsql
1.
2.
CREATE OR REPLACE TYPE SYS.ODCINumberList AS VARRAY(32767) of NUMBER
/


Даже в 10сятке есть!
можно бить на порции по 32тысячи на всякий случай


XMLTable поверх XMLSequence что-то не осилил
так? Проде быстрее процентов на 15-20 парсинг на 300 записях

select *
from xmltable('CARDS/C' passing(xmltype('
<CARDS>
<C NUM="1" /><C NUM="2" />
</CARDS>'
)) columns card_num number(10) path '@NUM' )
...
Рейтинг: 0 / 0
Список в запрос с клиента (почти списки в вьюхи :) )
    #39387409
Фотография barrabas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AmKadИ еще, .NET-овская (ORM-)гляделка может по дефолту не увидеть тип, если он доступен посредством синонима на объект в другой схеме.
...

ORM - зло
...
Рейтинг: 0 / 0
Список в запрос с клиента (почти списки в вьюхи :) )
    #39387416
Фотография AmKad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
barrabasXMLTable поверх XMLSequence что-то не осилил
так? Проде быстрее процентов на 15-20 парсинг на 300 записях

select *
from xmltable('CARDS/C' passing(xmltype('
<CARDS>
<C NUM="1" /><C NUM="2" />
</CARDS>'
)) columns card_num number(10) path '@NUM' )Да, так. Я это и имел в виду, когда писал xmltable вместо extractValue поверх xmlsequence.
...
Рейтинг: 0 / 0
Список в запрос с клиента (почти списки в вьюхи :) )
    #39387522
Фотография barrabas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Супер
Код: plsql
1.
select to_number(COLUMN_VALUE)  CARD_PP_NUM  from table(cast(:cardList as SYS.ODCINumberList))



+
Код: c#
1.
2.
3.
4.
5.
6.
7.
           
...IEnumerable<decimal> cardPpNums..
...

 var p = c.Parameters.Add("cardList", OracleDbType.Table);
            p.ObjectTypeName = "SYS.ODCINumberList";
            p.Value = cardPpNums;



вместо полторы минут стало 20 сек.

Код C# на Devart провайдере, т.к. сервис его использует, для ODP нужно по другому параметр объявлять (натыкался на примеры)

добавлю разбивку на партии по 32K и в прод :)
...
Рейтинг: 0 / 0
Список в запрос с клиента (почти списки в вьюхи :) )
    #39387573
Фотография AmKad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
barrabasСупер
Код: plsql
1.
select to_number(COLUMN_VALUE)  CARD_PP_NUM  from table(cast(:cardList as SYS.ODCINumberList))


COLUMN_VALUE - и так number. Да и без cast наверное можно обойтись.
...
Рейтинг: 0 / 0
Список в запрос с клиента (почти списки в вьюхи :) )
    #39387633
Фотография barrabas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AmKadbarrabasСупер
Код: plsql
1.
select to_number(COLUMN_VALUE)  CARD_PP_NUM  from table(cast(:cardList as SYS.ODCINumberList))


COLUMN_VALUE - и так number. Да и без cast наверное можно обойтись.
с to_number - да согласен

без каст работает, но ентерпрайс менеджер не может тюнинг запроса выполнить, ошибки выдаёт, уже не помню какую точно.
...
Рейтинг: 0 / 0
13 сообщений из 13, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Список в запрос с клиента (почти списки в вьюхи :) )
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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