Как вернуть датасет из хранимой процедуры?

 
0
 
Oracle
ava
Oleg | 19.11.2002, 19:11
Привет всем!
Вот если есть у меня хранимая процедура в Oracle8i БД,
например просто SELECT * FROm something... Как мне датасет отобразить в
делфячьей форме (не говорю в DBGrid)? В параметрах хр.проц. можно вернуть
тип данных ftCursor, в хелпе сказано, что возвращает курсор из Oracle.
Если это ключ, то как им пользоваться? Спасибо.
Comments (11)
ava
AntonSaburov | 21.11.2002, 22:11 #
Так никто и не ответил. Жаль. Очень хотелось бы знать. У меня было некое промежуточное решение с использованием временных таблиц. Процедура туда записывает, Следующий оператор - читает.
Но хотелось, чтобы как в MS SQL. Похоже не получится :(
ava
Medved | 22.11.2002, 05:55 #

Так никто и не ответил. Жаль. Очень хотелось бы знать.


Ладно поспешу опередить события и отвечу....

Да, дело в том, что если мы напишем в хранимой процедуре (и не только в ней. здесь имеется в виду, без каких либо компонент, т.е. напрямую) просто запрос SELECT * FROM MyTable то Oracle не воспримет такую конструкцию.... вернее он возвратит результат, но мы с ним ничего не сможем сделать..... это будет не набор данных (как мы это привыкли понимать, а такая "картинка") мы не сможем ни осуществлять навигацию по ней, ничего с ней сделать.... Oracle не позволяет (скорее всего по соображениям безопасности) осуществлять прямой доступ к таблицам.

Чтобы получить такой набор данных (в смысле "живой" с которым можно манипулировать, т.е. осуществлять навигацию и тд.), мы должны результаты какого-либо запроса, присвоить курсору (есть еще и другие подобные конструкции PL/SQL, такие как "записи" и "таблицы", но о них в другой раз)
Курсор - означает "текущий набор записей" и представляет из себя специальный элемент PL/SQL, с которым связан SQL-оператор SELECT.
Но отойдем от теории и рассмотрим пример:
У нас таблицы студентов (students), в которой четыре поля
0) ID;
1) Имя (Name);
2) Фамилия (Surname);
3) Курс (Kurs).


DECLARE
/* Обьявляем выходные переменные для хранения результатов запроса */
v_studentID students.ID%TYPE;
v_Name students.Name%TYPE;
v_SurName students.Surname%TYPE;

/* Переменная привязки, используемая в запросе */
v_kurs stusents.Kurs%TYPE := 2;

/* Создаем курсор */
CURSOR c_students IS
SELECT ID, Name, SurName
FROM students
WHERE kurs = v_kurs;

BEGIN
/* Открываем курсор */
OPEN c_students;

/* Начинаем цикл пробежки по записям */
LOOP
/* Сейчас выбирем каждую строку курсора (активного набора данных) в определенные нами переменные */
FETCH c_students INTO v_studentID, v_Name, v_SurName;
/* Если строки, которые нужно выбрать закончились, выйдем из цикла */
EXIT WHEN c_students%NOTFOUND;
END LOOP;

/* Закроем курсор */
CLOSE c_students;
END;


Здесь хотелось бы обратить ваше внимание на конструкции PL/SQL которые я использовал:

1) CURSOR <имя курсора> IS <запрос SELECT>. - создание курсора;
2) OPEN <имя курсора> - открытие курсора;
3) LOOP
<операторы;>
EXIT WHEN <условие выхода>;
END LOOP;
Это конструкция цикицеской обработки (читай - "цикл");
4) FETCH <имя курсора> INTO <список переменных куда заносяться результаты выборки>;
5) CLOSE <имя курсора>; - закрытие курсора;

Вот вообщем-то и все! Хотя это лишь сотая часть из того, что относиться к курсорам и вообще выборки записей из таблиц Oracle...

Но как я уже сказал... скоро будет цикл статей по этому поводу. Кому интересно, ждите....

P.S. Да, еще важно в конструкции - FETCH <имя курсора> INTO <список переменных куда заносяться результаты выборки>, чтобы количество переменных, в которые мы заносим результаты выборки из курсора, соответствовали типу и количеству полей, которые мы указываем после оператора SELECT, когда мы создаем курсор;
ava
AntonSaburov | 22.11.2002, 21:45 #
Г-н Pegas !
Был задан КОНКРЕТНЫЙ вопрос, а вы стали разводить непонятную теорию. Тот код, который приведен, то, что просилось изначально - НЕ ДЕЛАЕТ.
Нафига флейм разводить ? Показать свою осведомленность ?
Ну так заводите отдельную тему с циклом статей. А показательные примеры на уровне документации "для чайников" не надо !

Прошу рассматривать сие послание не как наезд или обвинение в профнепригодности, но хотелось услышать ответ на поставленный вопрос

МОЖНО ЛИ, И ЕСЛИ МОЖНО, ТО КАК ВЕРНУТЬ ИЗ ХРАНИМОЙ ПРОЦЕДУРЫ НА ORACLE
В ВИДЕ НАБОРА ДАННЫХ ?
Например, как в MS SQL.
ava
Medved | 23.11.2002, 02:43 #
Цитата


Г-н Pegas !

Был задан КОНКРЕТНЫЙ вопрос, а вы стали разводить непонятную теорию. Тот код, который приведен, то, что просилось изначально - НЕ ДЕЛАЕТ.

Нафига флейм разводить ? Показать свою осведомленность ?

Ну так заводите отдельную тему с циклом статей. А показательные примеры на уровне документации "для чайников" не надо !



Прошу рассматривать сие послание не как наезд или обвинение в профнепригодности, но хотелось услышать ответ на поставленный вопрос



МОЖНО ЛИ, И ЕСЛИ МОЖНО, ТО КАК ВЕРНУТЬ ИЗ ХРАНИМОЙ ПРОЦЕДУРЫ НА ORACLE

В ВИДЕ НАБОРА ДАННЫХ ?

Например, как в MS SQL.



Фу, какая невоспитанность....... на такой вопрос даже отвечать нехочется.....
ava
AntonSaburov | 23.11.2002, 03:05 #
Цитата (Pegas @ 22.11.2002, 18:43)
Цитата



МОЖНО ЛИ, И ЕСЛИ МОЖНО, ТО КАК ВЕРНУТЬ ИЗ ХРАНИМОЙ ПРОЦЕДУРЫ НА ORACLE


В ВИДЕ НАБОРА ДАННЫХ ?


Например, как в MS SQL.






Фу, какая невоспитанность....... на такой вопрос даже отвечать нехочется.....

Я действительно несколько вспылил. За что извиняюсь.
Но просто очень хотелось услышать ответ, который у меня изредка всплывает уже в течении нескольких лет. А воз и ныне там.
ava
Medved | 25.11.2002, 06:42 #
Да, не все так просто, как мне показалось, должен извиниться, надо работать не через курсор, а объявлять в качестве выходного параметра записи (имя_записи имя_таблицы%ROWTYPE), и используй в качестве компонентов для доступа к Oracle - библиотеку ODAC, я о ней раньше писал.... там есть такаой компонент OraStoredProc....
ava
AntonSaburov | 25.11.2002, 21:21 #
Цитата (Pegas @ 24.11.2002, 22:42)
Да, не все так просто, как мне показалось, должен извиниться, надо работать не через курсор, а объявлять в качестве выходного параметра записи (имя_записи имя_таблицы%ROWTYPE), и используй в качестве компонентов для доступа к Oracle - библиотеку ODAC, я о ней раньше писал.... там есть такаой компонент OraStoredProc....

А вот за эту идею - спасибо. Надо посмотреть. Мне тут знакомые тоже что-то такое посоветовали.
ava
Oleg | 26.11.2002, 03:36 #
Yes, people, we got it! smile smile smile
Читайте ЭТО!

create or replace table periods( -- создадим тестовую таблицу
pid varchar2(10),
name varchar2(3));
/

insert into periods(pid, name) values('1','JAN');
insert into periods(pid, name) values('2','FEB');
insert into periods(pid, name) values('3','MAR');
insert into periods(pid, name) values('4','APR');
insert into periods(pid, name) values('5','MAY');
insert into periods(pid, name) values('6','JUN');
insert into periods(pid, name) values('7','JUL');
insert into periods(pid, name) values('8','AUG');
insert into periods(pid, name) values('9','SEP');
insert into periods(pid, name) values('10','OCT');
insert into periods(pid, name) values('11','NOV');
insert into periods(pid, name) values('12','DEC');
/
create or replace type tRec as object( -- создадим обьектный тип для
pid varchar2(10), -- записи
name varchar2(3));
/

create or replace type tTab as table of tRec;
/ -- создаем таблицу записей

create or replace function f_Periods -- сама хранимая функция
return tTab as
p varchar2(10);
n varchar2(3);
res tTab:= tTab() ;
rec tRec:= tRec(p,n) ; -- инициализация составного типа
a Number;
cnt Number;
begin
select count(*) into cnt from periods;
for a in 1..cnt LOOP
Res.extend;
select pid, name into rec.pid, rec.name
from periods
where
pid = a;
res(a):= rec;
END LOOP;
RETURN Res;
end;
/

-- а вот и сам текст кверя
-- ОБРАТИТЕ ВНИМАНИЕ: cast

select * from table(cast(f_periods() as tTab));

Победа! :colgate

P.S. Кстати, вопрос к Pegas'у: я-то ODAC скачал, но я так понял,
что он триальный со всеми вытекающими...Что с ним сделать или
зачем он нужен тогда? Штука, согласен, неплохая.
ava
Medved | 28.11.2002, 06:45 #
Молодчинка!

P/S/ а по поводу ODAC я даже точно не знаю...... его мой коллега скачивал, но у меня он не триальный. Я завтра у него спрошу, что он там с ним вытворял :colgate и точно уже отвечу.... если что, через неделю я его на своем сайте выложу (пока кроме фото там ничего нет, можно не смотреть)....
ava
Medved | 29.11.2002, 05:59 #
Разузнал! Компоненты для прямого доступа к Oracle из Дельфи - ODAC и DAO находятся на сайте http://oraclebones.narod.ru

Там же лежит и SQL Developer - удобная штука между прочим!

З.Ы. все компоненты рабочии, не триальные...
ava
Oleg | 28.12.2002, 18:22 #
Спасибо, Pegas! :thumbs-up  Теперь подождем, когда oraclebones выложит
ODAC под Delphi7.
Please register or login to write.
Firm of day
Вы также можете добавить свою фирму в каталог IT-фирм, и публиковать статьи, новости, вакансии и другую информацию от имени фирмы.
Подробнее
Contributors
advanced
Submit