У меня есть много курсоров, которые возвращают строки с одинаковыми полями: поле числового идентификатора и поле XMLType. Каждый раз, когда я достигаю один из этих курсоров (каждый курсор теперь получил свою собственную функцию для доступа), я прохожу по той же схеме:Вопрос проектирования и реорганизации курсора
--query behind cursor is designed to no more than one row.
for rec in c_someCursor(in_searchKey => local_search_key_value) loop
v_id := rec.ID
v_someXMLVar := rec.XMLDataField
end loop;
if v_someXMLVar is null then
/* A bunch of mostly-standard error handling and logging goes here */
end if;
exception
/* all cursor access functions have the same error-handling */
end;
Поскольку картина стала более очевидной, это имело смысл централизовать его в одна функция:
function fn_standardCursorAccess(in_cursor in t_xmlCursorType, in_alt in XMLType) return XMLType is
v_XMLData XMLType;
begin
dbms_application_info.set_module(module_name => $$PLSQL_UNIT, action_name => 'fn_standardCursorAccess');
loop
fetch in_cursor
into v_XMLData;
exit when in_cursor%notfound;
end loop;
/*some additional standard processing goes here*/
return v_XML;
exception
/*standard exception handling happens here*/
end;
Проблема, с которой я столкнулся, заключается в вызове этой функции. Теперь я должен назвать это так:
open v_curs for select /*blah blah blah*/ where key_field = x and /*...*/;
v_data := fn_standardCursorAccess(v_curs,alt);
close v_curs;
То, что я хотел бы сделать, это назвать это так:
open v_curs for c_getSomeData(x);
v_data := fn_standardCursorAccess(v_curs,alt);
close v_curs;
... Причина в том, чтобы минимизировать количество изменений в мой код (Я не хочу, чтобы вырезать/вставить все эти курсоры к функциям, которые зависят от них, а в случае, когда несколько функций зависят от одного и того же курсора, мне придется обернуть это в новую функцию).
К сожалению, это не работает, Oracle возвращает ошибку говоря
Error: PLS-00222: no function with name 'C_GETSOMEDATA' exists in this scope
Это то, что я пытаюсь сделать даже можно?
(Oracle версия 10,2)
EDIT: Я думаю, что лучший способ описать то, что я делаю, это передать ссылку на явный курсор на функцию, которая будет выполнять некоторые общие процедуры на данные, возвращаемые курсором. Похоже, что я не могу использовать оператор open-for с курсором explcit, есть ли другой способ получить ссылку на явный курсор, чтобы я мог передать эту ссылку на функцию? Может быть, есть еще один способ, которым я мог бы подойти к этой проблеме?
EDIT: Копирование и вставка из моего предыдущего ответа на ответ R ван Рейн в:
Я попытался объявить курсор в спецификации пакета, и ссылаться на него с именем пакета: открытые v_curs для PKG.c_getSomeData (x); ... Это дает мне новую ошибку, говоря, что PKG.c_getSomeData должен быть функцией или массивом, которые будут использоваться таким образом.
UPDATE: Я говорил с нашим DBA здесь, он говорит, что это не возможно, чтобы иметь реф точку курсора в явный курсор. Похоже, я не могу этого сделать в конце концов. Облом. :(
Не могли бы вы разместить объявление 'c_getSomeData', которое используете? –
@Dougman: Есть много разных c_getSomeData. Все они следуют шаблону: 'Выберите T.ID, xmlelement (« SomeElt », ...) из T;' для многих разных 'T', конечно. – FrustratedWithFormsDesigner
Проблема заключается в том, что ошибка заключается в том, что C_GETSOMEDATA не существует в пределах области действия. Вы опубликовали почти все, кроме кода, имеющего отношение к ошибке *. Это, вероятно, архитектурная проблема. Но без соответствующей информации нам трудно помочь. Все, что мы можем сказать наверняка, - это не внутренняя структура 'c_getSomeData': это то, как и где они объявлены. – APC