|
|
|
новичок
      
участник
Last Login: 09.02.2002 12:05
Сообщ.: 3,
Visits: 34
|
|
Может вопросы слишком простые - изучаю Oracle только неделю. Но время жмет - кто знает помогите, если возможно, сразу кодом. В целом задача формулируется так (может кто знает ответ целиком): Нужна функция, которая будет получать имена двух таблиц, имя ключевого поля в одной таблице, его значение, имена первичного и внешнего ключей (по которому связывается с первой) и имя текстового поля - во второй и возвращать набор записей, которые можно обработать ADODB.Recordset и состоящий из первичного ключа и текстового поля второй таблицы.
1.Как получить набор записей из функции, желательно такой, который может быть обработан ADODB.Recordset? 2.Как полученный набор можно присвоить переменной типа table type или какой-либо еще?
Спасибо!
|
|
|
|
|
Forum Guru
      
участник
Last Login: 17.04.2003 15:55
Сообщ.: 69,
Visits: 760
|
|
create or replace package PKG_FUNC is
type RECORDSET is ref cursor; -- это тип результата
function FUNC(ID in number) return RECORDSET; -- эта ф-ция возвращает курсор, из которого фетчишь данные.
end; -- end of package
create or replace package body PKG_FUNC is
function FUNC(ID in number) return RECORDSET is VC RECORDSET; begin open VC from select * from EMPL where DEPT_ID=ID; return VC; end;
end; -- end of package body
Тип объявлять обязан. Теперь по поводу передачи имен двух таблиц и имен колонок - это тебе придется делать динамический PL/SQL, что тормознуто и вряд-ли оправдано. Возможно постановка задачи несколько другая - если подробнее расскажешь, то попытаюсь помочь.
|
|
|
|
|
новичок
      
участник
Last Login: 09.02.2002 12:05
Сообщ.: 3,
Visits: 34
|
|
Спасибо VVP за подробный ответ! Задача такая. Записи одной таблицы связаны друг с другом связью многие-ко-многим через таблицу пересечений. Не буду углубляться в предметику. На основе этого строится несимметричное дерево. Функция на выходе должна выдавать в наборе еще служебное поле, которое означает наличие связанных подчиненных строк для выбранной записи - это значит еще один курсор (жаль, if exists не работает в if - по-крайней мере так отвечает). По-поводу динамического SQL - абсолютно правильно. Я думал, может есть возможность как-то сработать указателями. Дело в том, что эта конструкция типовая и повторяется в схеме БД несколько раз, но ничего страшного - повешу на IF, хотя это менее эффективно.
Больше всего проблем возникает при считывании данных из функций: Если запустить select * from PKG_FUNC.FUNC(); выдает PLS-00103: Encountered the symbol "(" when expecting one of the following: . into bulk
Если пустить курсор:
declare rst recordset%rowtype;--recordset - то же тип, что возвращает FUNC type cur is ref cursor return recordset%rowtype; c cur; begin open c for select * from table(PKG_FUNC.FUNC()); fetch cur into rst; end; то PL/SQL: ORA-22905: cannot access rows from a non-nested table item
функция f(), которая возвращает тип table type операцией select * from f(); возвращает пустые строки. в тоде читаю курором, но разработчики клиентов не знают как к ней подобраться.
и т.п. и т.д.
читал в документации, что как-то применяют типы SYS.ANYTYPE, SYS.ANYDATASET, но это связано с применением DBMS_OUTPUT - до этого еще не добрался - читаю с компа с ораклового сайта, (ссылка на всякий: http://download-east.oracle.com/otndoc/oracle9i/901_doc/appdev.901/a89856/toc.htm) Не знаешь, где найти в сети такую же документацию на русском?
Спасибо!
|
|
|
|
|
Forum Guru
      
участник
Last Login: 17.04.2003 15:55
Сообщ.: 69,
Visits: 760
|
|
Для начала вот тебе ссылочка: http://otn.oracle.com/docs/products/oracle8i/content.html/ Там расписано про 8i сервак, а PL/SQL он и африке пиэльсиквел. Вот тебе еще ссылка про PL/SQL: http://otn.oracle.com/docs/products/oracle8i/doc_library/817_doc/appdev.817/a77069/toc.htm - читай там.
Теперь про курсор, открытый в ф-ции FUNC, вот одно из правильных обращений к нему из PL/SQL:
declare ID number := 12; VC PKG_FUNC.RECORDSET; V_EMPL EMPL%rowtype; begin VC:=PKG_FUNC.FUNC(ID); loop fetch VC into V_EMPL; exit when V_EMPL%notfound; dbms_output.put_line(V_EMPL.NAME||' '||V_EMPL.SURNAME); end loop; close VC; end;
Ладно я побежал, по русски только книги :-(
|
|
|
|
|
новичок
      
участник
Last Login: 09.02.2002 12:05
Сообщ.: 3,
Visits: 34
|
|
Спасибо! Прошу прощения, что настырничаю с вопросами, но время жмет и тактичность "перегружается" необходимостью. Что-то с этими функциями прямо беда. 1. Не получается внутри package (впрочем и standalone функцией) обратиться к функции: create or replace package PAK is type recordset is ref cursor; function F1(VAR number) return tbl_type; function F2 (VAR number) return recordset; end;
create or replace package body PAK as function F1(VAR) return tbl_type is ... end; function F2 (VAR) return recordset is rst recorset; begin open rst for select t.fld1,... from table([PAK.]F1(VAR)) -- что с префиксом PAK, что без него return rst; rnd;
пишет: PLS-00225: subprogram or cursor '[PAK.]F1' reference is out of scope
Возможно я не то горожу, но проблема в том, что нужно присвоить набор записей, возвращаемых функцией PL/SQL, ADOBDRecorset MS Visual Stidio? и в связи с этим вопросы:
2. MS Visual Studio: - КАК ВЫЗВАТЬ ИЗ ИЗ ПРИЛОЖЕНИЯ MS VS ФУНКЦИЮ И ПЕРЕДАТЬ/ПОЛУЧИТЬ ДАННЫЕ (бьемся второй день ничего не выходит) - во-первых, видит перегружаемые функции раздельно (какой тогда смысл перегрузки?), а в Object View функции packag-а вообще не видит - не получается получить значения в приложение MS VS у функции PL/SQL с возвращаемым типом table type - какие типы возвращаемых параметров можно присвоить ADODBRecorset (table type, cursor, pipelined)?
3. Можно ли вернуть из pipelined функции курсор?
Весьма признателен.
|
|
|
|
|
Forum Guru
      
участник
Last Login: 17.04.2003 15:55
Сообщ.: 69,
Visits: 760
|
|
| У вас аська или мыло есть? Давай туда...
|
|
|
|