powered by simpleCommunicator - 2.0.44     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Открытие курсора с помощью динамического SQL
7 сообщений из 7, страница 1 из 1
Открытие курсора с помощью динамического SQL
    #32051374
Katya
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Доброе время суток!

Мне необходима процедура открывающая курсор с помощью динамического SQL.
Я пыталась написать следующую процедуру :

TYPE CUR_TYP IS REF CURSOR ;
PROCEDURE NBGetCostCursor(
p_where VARCHAR2,
p_cursor IN OUT CUR_TYP
)
IS
v_cursor NUMBER := 0;
v_query VARCHAR2(1024) := '';
v_dummy INTEGER := 0;
BEGIN

v_cursor := DBMS_SQL.OPEN_CURSOR;

v_query := 'OPEN p_cursor FOR SELECT * FROM items ' || p_where ;

DBMS_SQL.PARSE(v_cursor,v_query,DBMS_SQL.V7);

v_dummy := DBMS_SQL.EXECUTE(v_cursor);

DBMS_SQL.CLOSE_CURSOR(v_cursor);

END NBGetCostCursor;

При запуске процедуры получаю сообщение об ошибке :

"SQL execution error, ORA-00900: invalid SQL statement"

В чём же моя ошибка ? Или версия Oracle8 устаревшая ?
...
Рейтинг: 0 / 0
Открытие курсора с помощью динамического SQL
    #32051389
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не умеет dbms_sql возвращать курсоры. Если у тебя оракл 8.0, то остается только явно указывать запрос:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
declare type t_refcursor is ref cursor;
           cr t_refcursor;
begin
  open cr for
    select * from scott.emp;
end;
/

А начиная с  8 . 1  есть Native SQL, например тот же самый зарос можно оформить строкой:

declare type t_refcursor is ref cursor;
           cr t_refcursor;
           v_sql varchar2( 64 ) := 'select * from scott.emp';
begin
  open cr for v_sql;
end;
/
...
Рейтинг: 0 / 0
Открытие курсора с помощью динамического SQL
    #32051490
vskv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
О... Интересно. А чем хендл курсора получаемый от DBMS_SQL.OPEN_CURSOR не годится.

Кстати, вопрос публике: а может ли процедура не закрыть курсор, вернуть этот самый хендл вызывающей её процедуре, а та потом отдаст его третьей процедуре, которая и будет работать с открытым курсором?
...
Рейтинг: 0 / 0
Открытие курсора с помощью динамического SQL
    #32051539
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А что можно сделать с этим самым "хендлом курсора" кроме того, что вызывать остальные процедуры пакета dbms_sql? Но на той схеме, что приведена в спецификации dbms_sql, или же на:

http://otn.oracle.com/docs/products/oracle9i/doc_library/release2/appdev.920/a96612/d_sql.htm#1001131

не упоминается возможность открыть курсор, пропарсить его со строкой 'select * from scott.emp', после чего отдать его для работы сторонней процедуре как ref cursor. По крайней мере у меня не получилось:) Если покажешь, как это делается- вправду, мне бы очень пригодилось, подобные задачи у нас встречаются.


Кстати о точности формулировок: у функции dbms_sql.open_cursor, как сказано:

-- Return value:
-- Cursor id number of the new cursor.

Именно "Cursor id", а не "Cursor handle".
...
Рейтинг: 0 / 0
Открытие курсора с помощью динамического SQL
    #32051550
Фотография killed
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2vskv делается неявно экземпляром. Т.е. при закрытии процессом курсора, Oracle все равно пытается удерживать макс. число курсоров, чтобы уменьшить издержки на их повторное использование.
...
Рейтинг: 0 / 0
Открытие курсора с помощью динамического SQL
    #32051800
vskv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 killed: Про открытие/закрытие курсоров, про hold_cursors, etc я прекрасно знаю.
Я имел ввиду такие вещи, как текущая запись (в смысле последняя профетченная) и т.п., которые при dbms_sql.close_cursor для текущей сессии теряют смысл.

2 Denis Popov: Ну если открыл курсор с помощью dbms_sql, то и продолжай с ним работать.

А насчёт терминологии -- я глубоко в отпуске, поэтому на такие мелочи внимания не обращаю. Пользы от этого идентификатора, если всё равно честно его использовать можно только через тот же dbms_sql?

А с ref cursor на динамически формируемый запрос обычно начинаются вопросы типа "а как определить число полей, их тип и т.п."...
...
Рейтинг: 0 / 0
Открытие курсора с помощью динамического SQL
    #32051849
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Отпуск... завидую.

Польза от Cursor Id только в том, чтобы дергать остальные процедуры dbms_sql.. Я пытался сопоставить его с чем-нибудь в, к примеру, v$sql, v$open_cursor - никакой корреляции не нашел:(

Определение полей в ref cursore, как в прочем, и в dbms_sql, по идее остаются на совести разработчика- если ошибешься, то при первом же фетче об этом узнаешь. Ref Cursor можно доопределит как, к примеру:

Код: plaintext
1.
2.
declare type t_record is record (a number, b varchar2( 8 ));
        type t_refcursor is ref cursor return t_record;


Плохо другое:


через dbms_sql не получается открывать курсоры, но можно привязывать параметры по имени;

через open .. for .. using.. можно получить ref cursor, но параметры привязываются только по порядку.

В случае сложных динамических запросов, когда неизвестно, какие именно и/или в какой порядке будут в нем параметры, приходится выкручиваться, используя одновременно и dbms_sql, и open for. Но в 9-ке они вполне дополняют друг друга, это я про Table Functions.
...
Рейтинг: 0 / 0
7 сообщений из 7, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Открытие курсора с помощью динамического SQL
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]