function User_SELECT
(
aID in integer,
aFIO_F in varchar2,
aFIO_N in varchar2,
aFIO_O in varchar2,
aLogin in varchar2,
aPassword in varchar2,
aEnable in number
)Return ref_search_result
IS
aUser ref_search_result;
BEGIN
open aUser for
select ID,
Fio_f,
FIO_N,
FIO_O,
Login,
Password,
isEnable
FROM USERSES
WHERE (ID=aID or aID is null) and
(FIO_F=aFIO_F or aFIO_F is null) and
(FIO_N=aFIO_N or aFIO_N is null) and
(FIO_O=aFIO_O or aFIO_O is null) and
(Login=aLogin or aLogin is null) and
(Password=aPassword or aPassword is null) and
(isEnable=aEnable or aEnable is null);
return auser;
END User_SELECT;
Функция компилится и работает.
Так вот как мне сделать выборку данных из этой функции. Что то типа
select * from admin_packages.user_select(null,null,null,null,null,null,null);
Здравствуйте, Softwarer, Вы писали:
S>Здравствуйте, Аноним, Вы писали:
S>Убери
А>>type ref_search_result is ref cursor;
S>и сделай возвратом функции sys_refcursor.
Ну и что абсолютно ничего не изменилось.
select * from ADMIN_PACKAGES.USER_SELECT(null, null, null, null, null, null, null);
Оракле выдает ошибку ORA-00933 SQL Comand Not properly ended
Не уж то в оракле так сложно сделать селект из функции?
wrote: > > select * from ADMIN_PACKAGES.USER_SELECT(null, null, null, null, null, > null, null); >
Так вызывать функцию возващающую курсор нельзя.
Если ты вызываешь эту функцию в PL/SQL коде, то ты должен объявить перед
этим переменную курсора, и ей присвоить вызов функции.
declare
ref_cursor is ref cursor;
begin
ref_cursor := ADMIN_PACKAGES.USER_SELECT(null, null, null, null, null,
null, null);
loop
fetch ref_cursor into ...
exit when ref_cursor%notfound;
end loop;
end;
Если ты хочешь чтобы тебе вернулся DataSet на клиента, в зависимости от
библиотек, через которые ты вызываешь свою фукцию, в цикле также
перебираешь курсор пока он не кончится.
Хорошо, как мне построить функцию, что бы ее можно было так вызывать?
__>Если ты вызываешь эту функцию в PL/SQL коде, то ты должен объявить перед __>этим переменную курсора, и ей присвоить вызов функции. __>
__>declare
__> ref_cursor is ref cursor;
__>begin
__> ref_cursor := ADMIN_PACKAGES.USER_SELECT(null, null, null, null, null,
__>null, null);
__> loop
__> fetch ref_cursor into ...
__> exit when ref_cursor%notfound;
__> end loop;
__>end;
__>
__>Если ты хочешь чтобы тебе вернулся DataSet на клиента, в зависимости от __>библиотек, через которые ты вызываешь свою фукцию, в цикле также __>перебираешь курсор пока он не кончится.
Клиент меня пока не интересует. я только начинаю разбиратся с ораклом.
Хотя конечно интересно, как реализовать функцию, процедуру, что бы ее вызвать со стороны клиента и получить DataSet, без организации курсора
wrote: > >> > >> > select * from ADMIN_PACKAGES.USER_SELECT(null, null, null, null, null, >> > null, null); >> > > __>Так вызывать функцию возващающую курсор нельзя. > > Хорошо, как мне построить функцию, что бы ее можно было так вызывать? >
Так как ты написал, так нельзя вызывать. неверный синтаксис. > Клиент меня пока не интересует. я только начинаю разбиратся с ораклом. > Хотя конечно интересно, как реализовать функцию, процедуру, что бы ее > вызвать со стороны клиента и получить DataSet, без организации курсора
Без курсора — "чистый" SELECT вызванный на клиенте вернет тебе DataSet.
Posted via RSDN NNTP Server 1.9
Re[6]: Я просто туплю Oracle
От:
Аноним
Дата:
22.07.05 07:37
Оценка:
Здравствуйте, _kdv_, Вы писали:
__> wrote: >> >>> > >>> > select * from ADMIN_PACKAGES.USER_SELECT(null, null, null, null, null, >>> > null, null); >>> > >> __>Так вызывать функцию возващающую курсор нельзя. >> >> Хорошо, как мне построить функцию, что бы ее можно было так вызывать? >> __>Так как ты написал, так нельзя вызывать. неверный синтаксис.
Это я уже понял, что синтаксис не верный. Вопрос накой как мне сделать функцию, которая возвращает Датасет? >> Клиент меня пока не интересует. я только начинаю разбиратся с ораклом. >> Хотя конечно интересно, как реализовать функцию, процедуру, что бы ее >> вызвать со стороны клиента и получить DataSet, без организации курсора __>Без курсора — "чистый" SELECT вызванный на клиенте вернет тебе DataSet.
То есть селект из таблицы?
Нет это не есть хорошо, никогда не приветствовал такой подход. Таблицы с клиента должны быть вообще не доступны, на худой конец селект из представления, а лучше всего пользовать процедуры и функции, конечно может быть я устарел.....
wrote: > > Это я уже понял, что синтаксис не верный. Вопрос накой как мне сделать > функцию, которая возвращает Датасет? >
Ну начал ты правильно. Т.е. в функции ты просто открываешь курсор
корректным SELECT-запросом. Вызываешь ее на клиенте и в цикле считываешь
все строчки. > >Таблицы с > клиента должны быть вообще не доступны, на худой конец селект из > представления, а лучше всего пользовать процедуры и функции, конечно > может быть я устарел.....
Это хороший подход.
Здравствуйте, Аноним, Вы писали:
А>Нет это не есть хорошо, никогда не приветствовал такой подход. Таблицы с клиента должны быть вообще не доступны, на худой конец селект из представления, а лучше всего пользовать процедуры и функции, конечно может быть я устарел.....
Для оракла между этими подходами нет серьезной разницы, вопрос в том, как наиболее удобно с точки зрения организации клиентского приложения.
Скажем, если приложение активно пользуется ad-hoc запросами, оборачивать их в процедуры — дурная трата сил. Для постоянных запросов процедуры или view предпочтительнее, поскольку держать их на сервере удобнее для разработки (автоматическая постоянная проверка корректности итп).
А>Хорошо, как мне построить функцию, что бы ее можно было так вызывать?
-- Тип записи, который будет возвращать запрос
SQL> create or replace type all_objects_row as object
2 (
3 object_id number,
4 object_name varchar2(30)
5 );
6 /
Type created.
--Табличный тип для записей
SQL> create or replace type all_objects_row_t as table of all_objects_row;
2 /
Type created.
--pipelined табличная функция для возврата результата. Условие where будет передаваться в качестве параметра этой функции, из которого мы будем формировать ref cursor для возврата результата.
SQL> create or replace function test(
2 p_where varchar2
3 ) return all_objects_row_t pipelined is
4 type ref_cursor is ref cursor;
5 l_cur ref_cursor;
6 type cur_row is record (object_id number, object_name varchar2(30));
7 type cur_row_array is table of cur_row index by binary_integer;
8 l_buffer cur_row_array;
9 begin
10 open l_cur for 'select object_id, object_name from all_objects '||p_where;
11
12 loop
13 fetch l_cur bulk collect into l_buffer limit 1000;
14
15 for i in 1 .. l_buffer.count
16 loop
17 pipe row (all_objects_row(l_buffer(i).object_id, l_buffer(i).object_name));
18 end loop;
19
20 exit when l_cur%notfound;
21 end loop;
22
23 close l_cur;
24 return;
25 end;
26 /
Function created.
Function created.
--Теперь из этой функции можно делать обычные выборки
SQL> select * from table(test('where object_id=30048'));
OBJECT_ID OBJECT_NAME
---------- ------------------------------
30048 SQLDEFINITIONSEQUENCE
SQL> select * from table(test('where object_name=''TEST'''));
OBJECT_ID OBJECT_NAME
---------- ------------------------------
43274 TEST
SQL> select * from table(test(null)) where object_name='TEST';
OBJECT_ID OBJECT_NAME
---------- ------------------------------
43274 TEST
Помните — на табличных функциях не может быть индекса, именно поэтому зачастую лучше передавать where в качестве параметра, чем накладывать условие where на результат выборки из табличной функции.
Re[6]: Я просто туплю Oracle
От:
Аноним
Дата:
22.07.05 08:36
Оценка:
Здравствуйте, Quadro, Вы писали:
А>>Хорошо, как мне построить функцию, что бы ее можно было так вызывать?
Q>
Q>-- Тип записи, который будет возвращать запрос
SQL>> create or replace type all_objects_row as object
Q> 2 (
Q> 3 object_id number,
Q> 4 object_name varchar2(30)
Q> 5 );
Q> 6 /
Q>Type created.
Q>--Табличный тип для записей
SQL>> create or replace type all_objects_row_t as table of all_objects_row;
Q> 2 /
Q>Type created.
Q>--pipelined табличная функция для возврата результата. Условие where будет передаваться в качестве параметра этой функции, из которого мы будем формировать ref cursor для возврата результата.
SQL>> create or replace function test(
Q> 2 p_where varchar2
Q> 3 ) return all_objects_row_t pipelined is
Q> 4 type ref_cursor is ref cursor;
Q> 5 l_cur ref_cursor;
Q> 6 type cur_row is record (object_id number, object_name varchar2(30));
Q> 7 type cur_row_array is table of cur_row index by binary_integer;
Q> 8 l_buffer cur_row_array;
Q> 9 begin
Q> 10 open l_cur for 'select object_id, object_name from all_objects '||p_where;
Q> 11
Q> 12 loop
Q> 13 fetch l_cur bulk collect into l_buffer limit 1000;
Q> 14
Q> 15 for i in 1 .. l_buffer.count
Q> 16 loop
Q> 17 pipe row (all_objects_row(l_buffer(i).object_id, l_buffer(i).object_name));
Q> 18 end loop;
Q> 19
Q> 20 exit when l_cur%notfound;
Q> 21 end loop;
Q> 22
Q> 23 close l_cur;
Q> 24 return;
Q> 25 end;
Q> 26 /
Q>Function created.
Q>Function created.
Q>--Теперь из этой функции можно делать обычные выборки
SQL>> select * from table(test('where object_id=30048'));
Q> OBJECT_ID OBJECT_NAME
Q>---------- ------------------------------
Q> 30048 SQLDEFINITIONSEQUENCE
SQL>> select * from table(test('where object_name=''TEST'''));
Q> OBJECT_ID OBJECT_NAME
Q>---------- ------------------------------
Q> 43274 TEST
SQL>> select * from table(test(null)) where object_name='TEST';
Q> OBJECT_ID OBJECT_NAME
Q>---------- ------------------------------
Q> 43274 TEST
Q>
Q>Помните — на табличных функциях не может быть индекса, именно поэтому зачастую лучше передавать where в качестве параметра, чем накладывать условие where на результат выборки из табличной функции.
Ну пример из книжки я и сам смог прочитать, хотя спасибо за внимание.
Вы мне пример привидите с моей таблицей, а не с объектом Оракловым
А>Вы мне пример привидите с моей таблицей, а не с объектом Оракловым
Я привел концепцию построение подобных вещей. Чем Ваш случай принципиально отличается от того что привел я?
Ничем. Если вы поймете мой пример — то без труда напишите и свой.
Re[8]: Я просто туплю Oracle
От:
Аноним
Дата:
22.07.05 08:40
Оценка:
Здравствуйте, _kdv_, Вы писали:
__> wrote: >> >> Это я уже понял, что синтаксис не верный. Вопрос накой как мне сделать >> функцию, которая возвращает Датасет? >> __>Ну начал ты правильно. Т.е. в функции ты просто открываешь курсор __>корректным SELECT-запросом. Вызываешь ее на клиенте и в цикле считываешь __>все строчки.
Я в меру своей тупости не понимаю или Вы в меру своего взгляда сверху ленитесь объяснить или просто не можите ответить на конкретный вопрос, постоянно уходите от ответа.
Внимание вопрос.
Как мне сделать функцию, которая возвращает ДАТАСЕТ, что бы ее можно было использовать в СЕЛЕКТЕ.
SELECT ID FROM myFunction.
Если сделать такую функцию нельзя или Вы не знаите ответ, то так и напишите.