Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 Получение набора данных из ХП  [new]
maxa
Member

Откуда:
Сообщений: 27
Есть клиент Delphi+DOA. Подскажите пожалуйста, как вызвать хранимую процедуру,возвращающую набор данных.?
Процедура может вернуть данные только через курсор?
4 сен 03, 16:21    [326682]     Ответить | Цитировать Сообщить модератору
 Re: Получение набора данных из ХП  [new]
Borland
Member

Откуда: $HOME
Сообщений: 15839
А что мешает использовать TStoredProc ?
4 сен 03, 16:28    [326705]     Ответить | Цитировать Сообщить модератору
 Re: Получение набора данных из ХП  [new]
maxa
Member

Откуда:
Сообщений: 27
спасибо, попробую...но проблема в другом: процедуру мне удалось вызвать из
TOracleDataSet, а вот НД она не возвращает. Очевидно ошибка в самой процедуре. Можно какой-нибудь пример ХП?
4 сен 03, 16:47    [326762]     Ответить | Цитировать Сообщить модератору
 Re: Получение набора данных из ХП  [new]
Borland
Member

Откуда: $HOME
Сообщений: 15839
Привяжите к TOraQuery
4 сен 03, 16:48    [326766]     Ответить | Цитировать Сообщить модератору
 Re: Получение набора данных из ХП  [new]
maxa
Member

Откуда:
Сообщений: 27
Уважаемый Borland, а привязка к TOraQuery носит обязательный характер?
свойство SQL TOracleDataSet:
begin
select * from my_stored_proc(?param)
end
Только НД все равно пуст. Есть ли ошибка в синтаксисе вызова?
4 сен 03, 16:57    [326791]     Ответить | Цитировать Сообщить модератору
 Re: Получение набора данных из ХП  [new]
Borland
Member

Откуда: $HOME
Сообщений: 15839
Прошу прощения за оффтоп и долгое молчание - не было возможности выйти в инет:-((
Попробуйте сделать следующее: создать в TStoredProc выходные параметры и в цикле while no StoredProc.Eof обрабатывать НД
10 сен 03, 19:35    [334019]     Ответить | Цитировать Сообщить модератору
 Re: Получение набора данных из ХП  [new]
dragonx
Member

Откуда: Vladivostok - Москва - ...
Сообщений: 564
TstoredProc luche ne ispolzovat` - krivaya ona, potom problemm budet mnogo,
raz ispolzuesh DOA, tak i ispolzui, a xranimuu proceduru vizivai iz PL/SQL blocka, zaidi na forum Delphi, tam eta problemma obsujdalas`
11 сен 03, 04:21    [334209]     Ответить | Цитировать Сообщить модератору
 Re: Получение набора данных из ХП  [new]
sergeyyy71
Member

Откуда: Shatura City, Moscow region
Сообщений: 41
Есть несколько разных путей.
1. Воспользваться передачей набора данных через DML array. Это самое простое. Это можно сделать только через TOracleQuery.
2. Если хранимая функция возвращает или передает через out параметр скалярную PL/SQL таблицу, то можно в Дельфи создать переменную, инкапсулирующую такую таблицу, и передать ее в качестве параметра вызываемой хранимой функции. К сожалению, у меня не получилось работать таким образом с PL/SQL таблицами, основанными на записях (с несколькими полями)
3. Создать в базе данных пользовательский тип коллекции и написать Хранимую Функцию так, чтобы она возвращала/передавала такой тип. В Дельфи создать переменную типа TOracleObject и передать ее при вызове хранимой функции.
12 сен 03, 08:33    [336008]     Ответить | Цитировать Сообщить модератору
 Re: Получение набора данных из ХП  [new]
DimaR
Member

Откуда:
Сообщений: 1570
Уважаемый Borland, а привязка к TOraQuery носит обязательный характер?
свойство SQL TOracleDataSet:
begin
select * from my_stored_proc(?param)
end


Только НД все равно пуст. Есть ли ошибка в синтаксисе вызова?

Да есть,
В данном случае не select, а
open cursor :ret for select

Где ret в DataSet variables обьявить как возвращаемую cursor
12 сен 03, 10:26    [336207]     Ответить | Цитировать Сообщить модератору
 Re: Получение набора данных из ХП  [new]
Алексей Черепанов
Member

Откуда: Краснодар
Сообщений: 423
Я уже несколько лет не привязывал друг к другу DataSet и DataSource ;)), но насколько я помню, дело по данному вопросу состояло так:

1. Оракл может возвратить DataSet если процедура описана в пакете и её параметр описан так -

create package .....
type cur is ref cursor;
procedure PP (DS in out cur);
....

create package body .....
procedure PP (DS in out cur)
as
begin
open DS for select .. from ....;
end;

Далее. В дельфи берётся TStoredProc, у него указывается имя процедуры в виде ПАКЕТ.ПРОЦЕДУРА (именно большими буквами:) и в параметрах заводится соответствующий параметр. Я не скажу сейчас, как лучше, потому что всё время делал это динамически, а потому за прошествием лет и не помню.

А вот дальше берёшь DataSource - и привязываешь в DataSource в качестве DataSet = твой StoredProc.
После её открытия всё получится.

Единственный по-моему большой недостаток всей этой схемы заключается в том, что в самой процедуре невозможно руками сформировать набор данных кроме как через SELECT. Иногда надо по-другому, а не получается.
12 сен 03, 10:33    [336217]     Ответить | Цитировать Сообщить модератору
 Re: Получение набора данных из ХП  [new]
pavelf
Member

Откуда:
Сообщений: 13
>>Единственный по-моему большой недостаток всей этой схемы заключается >>в том, что в самой процедуре невозможно руками сформировать набор >>данных кроме как через SELECT. Иногда надо по-другому, а не получается.

Всмысле?
12 сен 03, 11:17    [336342]     Ответить | Цитировать Сообщить модератору
 Re: Получение набора данных из ХП  [new]
maxa
Member

Откуда:
Сообщений: 27
Спасибо всем кто отозвался, все получилось.Писал вызов ХП с синтаксисом Interbase,не обнаружив в документации похожего вопроса...ну и пытался лбом пробить стену :).
to DimaR - спасибо за пример, его и не хватало.
to Borland - от TStoredProc отказался по причине, указанной dragonx.
12 сен 03, 12:49    [336603]     Ответить | Цитировать Сообщить модератору
 Re: Получение набора данных из ХП  [new]
Алексей Черепанов
Member

Откуда: Краснодар
Сообщений: 423
pavelf> Всмысле?

В том смысле, что я, например, не могу сам мостряпать произвольный набор данных никак кроме через select
И если я хочу возвращать такой набор данных -
11 12 13 14
21 22 23 24
31 32 33 34
то я должен буду в процедуре написать

open DS for
select 11,12,13,14
union
select 21,22,23,24
union
select 31,32,33,34
from dual

Больше никак
(тут я не стал писать select с правильным синтаксисом - думаю и так понятно)
15 сен 03, 15:14    [338996]     Ответить | Цитировать Сообщить модератору
 Re: Получение набора данных из ХП  [new]
CM Hungry
Member

Откуда:
Сообщений: 207
Все можно. И вернуть набор данных, который сам делаешь - можно. Только столбцы заранее известны должны быть. Произвольный набор столбцов - не вернуть.


create or replace type ic_rec_type is object(
unique_id integer,
name varchar2(255),
parent_id integer,
depth integer,
parentname varchar2(255),
ownerlogin varchar(32),
rec_type integer,
numchildren integer,
numpages integer);
/

create or replace type ic_tbl_type is table of ic_rec_type;
/

CREATE OR REPLACE FUNCTION f_GetTree(aparent in integer, adepth in integer)
RETURN ic_tbl_type
AS
retval ic_tbl_type := ic_tbl_type();
cursor cats_cur(cparent integer, cdepth integer) is
select c1.*, level as depth from shortcatview c1
where
level <= cdepth
connect by prior c1.unique_id = c1.parent_id
start with c1.unique_id = cparent;
cats_rec shortcatview%ROWTYPE;
cursor items_cur(acat integer) is
select i.* from ItemFullInfoView i
where i.deleted = 0 and i.category_id = acat;
items_rec ItemFullInfoView%rowtype;
nc integer;
np integer;
begin
FOR cats_rec in cats_cur(aparent, adepth) LOOP
retval.extend;
select count(*) into nc from categories c where c.parent_id=cats_rec.unique_id and c.deleted = 0;
select count(*) into np from items i where i.category_id=cats_rec.unique_id and i.deleted = 0;
retval(retval.count) := ic_rec_type(cats_rec.unique_id, cats_rec.name, cats_rec.parent_id, cats_rec.depth, cats_rec.parentname, cats_rec.ownerlogin, 0, nc, np);
for items_rec in items_cur(cats_rec.unique_id) loop
retval.extend;
retval(retval.count) := ic_rec_type(items_rec.unique_id, items_rec.name, items_rec.category_id, cats_rec.depth+1, cats_rec.name, items_rec.ownername, 1, 0, 0);
end loop;
END LOOP;

RETURN retval;

end;
/



А получать из нее данные -

select *
from the ( select cast( f_GetTree(0,6) as ic_tbl_type ) from dual ) a

Оракл 8.1.7ЕЕ, Вин2К.

В Оракл9 есть pipe, аналог интербазовского suspend.
15 сен 03, 20:28    [339536]     Ответить | Цитировать Сообщить модератору
 Re: Получение набора данных из ХП  [new]
pavelf
Member

Откуда:
Сообщений: 13
>>Алексей Черепанов

наверно я что-то непонимаю, приведите более реальный пример когда нельзя вернуть произвольный набор данных?
или что вы подразумеваете под "произвольным" набором данных?
мне кажется что возможостей PL/SQL достаточно для формирования (обработки) наборов данных, в крайнем случии из хранимки можно вернуть данные в XML формате или несколько наборов данных.
16 сен 03, 04:25    [339787]     Ответить | Цитировать Сообщить модератору
 Re: Получение набора данных из ХП  [new]
Алексей Черепанов
Member

Откуда: Краснодар
Сообщений: 423
То, что я имел в виду - это заполнение неопределённой матрицы значениями.
Всё же остальное можно сделать через select. В частности, по-моему, и предыдущий пример от CM Hungry - тоже.
16 сен 03, 11:50    [340277]     Ответить | Цитировать Сообщить модератору
 Re: Получение набора данных из ХП  [new]
CM Hungry
Member

Откуда:
Сообщений: 207
Через select далеко не все можно сделать. Например, когда нужна выборка по всем датам, от 01.01.2003 до 31.01.2003, а счета есть не за все эти даты. Можно костыль в виде таблицы дат подставить, конечно, но так ли это нужно.
А вот вернуть произвольный набор столбцов... Напрямую нельзя, через dynamic sql - можно, и не такое можно.
16 сен 03, 13:27    [340514]     Ответить | Цитировать Сообщить модератору
 Re: Получение набора данных из ХП  [new]
DimaR
Member

Откуда:
Сообщений: 1570
to CM Hungry
В 9i есть типы
anydata
anydataset

Там вроде можно, чего угодно сгенерить.
16 сен 03, 13:43    [340567]     Ответить | Цитировать Сообщить модератору
 Re: Получение набора данных из ХП  [new]
CM Hungry
Member

Откуда:
Сообщений: 207
DimaR: так то в 9... А в 8 - увы.
16 сен 03, 16:20    [341022]     Ответить | Цитировать Сообщить модератору
Между сообщениями интервал более 1 года.
 Re: Получение набора данных из ХП  [new]
Камасутр
Guest
А вот еще вопросик в догонку.
Мы заполняем табличный тип по курсору используя:
[SRC oracle]....
retval.extend;
retval(retval.count) := ic_rec_type(items_rec.unique_id, items_rec.name, items_rec.category_id, cats_rec.depth+1, cats_rec.name, items_rec.ownername, 1, 0, 0);SRC]
Работает отлично.
Подскажите, как не добавлять, а обновить текущую запись в retval?
12 дек 06, 06:42    [3521666]     Ответить | Цитировать Сообщить модератору
 Re: Получение набора данных из ХП  [new]
Elic
Member

Откуда:
Сообщений: 29979
Камасутр
retval.extend;
Подскажите, как не добавлять, а обновить текущую запись в retval?
RTFM
12 дек 06, 08:24    [3521774]     Ответить | Цитировать Сообщить модератору
 Re: Получение набора данных из ХП  [new]
Камасутр
Guest
Ekic, спасибо - как раз то, что надо. ))))
12 дек 06, 13:39    [3524078]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить