Что такое код ovrimos_cursor

Мониторинг открытых и кэшированных курсоров и ошибка ORA-01000

Здесь слово «разбор» используется в смысле p a rse, соответственно «мягкий разбор» и «жёсткий разбор» – « soft parse » и « hard parse ».

[В квадратных скобках я ввожу свои поясняющие фразы, перевод фраз или фразы из оригинала]

Чуть ли не каждый администратор БД имел дело с ошибкой ORA-01000, «Maximum open cursors exceeded» [превышено максимальное число открытых курсоров]. В этой статье будут обсуждаться параметры инициализации, которые влияют на открытые курсоры, разница между открытыми и кэшированными курсорами, закрытие курсоров и, собственно, мониторинг открытых и кэшированных курсоров.

Открытые курсоры [ Open Cursors ]

Открытые курсоры находятся в shared pool [разделяемом пуле], в library cache [библиотечном кэше]. Для того, чтобы какая-нибудь сессия не заполнила библиотечный кэш или не загрузила бы CPU миллионами запросов разбора операторов ( parse requests ) «под завязку», выставляется параметр OPEN_CURSORS.

Параметр OPEN_CURSORS определяет максимальное количество открытых курсоров на одну сессию в каждый момент времени. Например, если OPEN_CURSORS равен 1000, то в любой сессии в любой момент времени могут быть открытыми одновременно до 1000 курсоров. Если же какая-то сессия уже имеет количество открытых курсоров, равное значению параметра OPEN_CURSORS, то при попытке открыть хотя бы ещё один курсор, она получит ошибку ORA-01000.

Значение параметра OPEN_CURSORS по умолчанию равно 50, однако Oracle рекомендует для большинства приложений выставлять его равным, по меньшей мере, 500. Некоторым приложениям может потребоваться ещё большее значение, например, web-приложениям, которые обслуживают по нескольку сотен пользователей, совместно использующих пул сессий. Том Кайт рекомендует выставлять его равным 1000.

Кэшированные курсоры сессии [ Session Cached Cursors ]

На курсоры влияют два параметра инициализации: OPEN_CURSORS и SESSION_CA C HED_CURSORS, которые часто приводят к путанице.

SESSION_CA C HED_CURSORS определяет количество кэшированных закрытых курсоров, которое может быть в одной сессии.

[ Отступление . Из документации по Oracle 9i Release 2 SESSION_CACHED_CURSORS lets you specify the number of session cursors to cache. Repeated parse calls of the same SQL statement cause the session cursor for that statement to be moved into the session cursor cache. Subsequent parse calls will find the cursor in the cache and do not need to reopen the cursor. Oracle uses a least recently used algorithm to remove entries in the session cursor cache to make room for new entries when needed.

Вы можете выставить значение этого параметра любым, безотносительно к значению OPEN_CURSORS. Этот параметр не приводит к появлению ошибки ORA-01000 и не влияет на количество открываемых сессией курсоров. И наоборот, параметр OPEN_CURSORS не оказывает влияния на количество кэшируемых курсоров. Между этими двумя параметрами связи не существует.

Значение параметра SESSION_CA C HED_CURSORS по умолчанию равно 0, и для любой сессии ни один курсор не будет кэширован. (Курсоры, однако, окажутся кэшированными в разделяемом пуле, но сессии придётся их там искать.) Если же параметру SESSION_CA C HED_CURSORS присвоено отличное от нуля значение, то по результатам запроса на разбор [ parse request ] Oracle проверяет наличие в библиотечном кэше более трёх запросов на разбор для того же предложения. При положительном результате проверки Oracle перемещает связанный с этим предложением курсор сессии в кэш курсоров сессии [ session cursor cache ]. Последующие запросы на разбор для того же предложения в той же сессии заполняются из кэша курсоров сессии – таким образом исключается даже мягкий разбор [ soft parse ]. (Совсем избежать мягкого разбора технически невозможно – производится «более мягкий» мягкий разбор, то есть более быстрый и требующий меньших затрат CPU)

В кэше курсоров сессии Oracle управляет кэшированными курсорами с использованием LRU-списка. Когда окажется, что количество закрытых кэшированных курсоров равно SESSION_CA C HED_CURSORS, Oracle начнёт «удалять закрытые курсоры» из «холодного конца» LRU-списка с целью освободить место для кэширования нового курсора.

Зачем кэшировать курсоры?

Очевидное преимущество от кэширования курсоров сессией состоит в уменьшении количества разборов, что приводит в целом к более быстрым временам выполнения. Это особенно касается таких приложений, как Oracle Forms, в которых переключение от одной формы к другой вызывает закрытие всех открытых для этой формы курсоров сессии. Обратное переключение к предыдущей форме открывает точно такие же курсоры, какие были закрыты. Как видим, кэширование курсоров сессией действительно приводит к снижению количества повторных разборов.

Более того, имеется ещё одно преимущество. Так как в случае кэширования курсоров сессии не нужно искать в библиотечном кэше прежде разобранные SQL-выражения, это приводит к уменьшению защёлок библиотечного кэша и разделяемого пула. Такие защёлки часто становятся точками конкуренции в нагруженных OLTP-системах. Уменьшение количества защёлок сокращает количество ожиданий защёлок, приводящее не столько к выигрышу в скорости, сколько к росту масштабируемости системы.

Мониторинг открытых курсоров

Я уверена [автор статьи – женщина], что много путаницы касательно открытых и кэшированных курсоров возникает из-за самих названий d ynamic p erformance v iews (V$) [представления динамических характеристик] Oracle, которые используются, в том числе, для отслеживания таких курсоров. Представление V $ OPEN _ CURSORS показывает кэшированные сессией курсоры, никак не открытые в данный момент времени. Если вас вдруг заинтересует, сколько курсоров ваша сессия открыла в настоящий момент, не используйте для этой цели V $ OPEN _ CURSORS . Оно показывает курсоры в кэше курсоров сессии для каждой текущей сессии, а не действительно открытые курсоры.

Для отслеживания открытых курсоров запрашивайте представление V$SESSTAT с предикатом name=’opened cursors current’. Оно покажет количество открытых в настоящее время курсоров на сессию:

—общее количество открытых курсоров на сессию

Если вы запустили несколько N-уровневых приложений со множеством web-серверов, вам может оказаться полезнее поиск открытых курсоров по usern a me и mashine :

—общее количество открытых курсоров по usern a me и mashine

Наилучший совет по настройке параметра OPEN_CURSORS – это не настраивать его. Выставьте его значение достаточно высоким, чтобы больше не беспокоиться об этом. Если ваши сессии работают очень близко к ограничению, которое вы задали параметром OPEN_CURSORS, то просто увеличьте его. При настройке этого параметра ваша цель состоит в том, чтобы при нормальной работе не возникало ошибки ORA -01000.

Значение параметра OPEN_CURSORS вовсе не означает, что теперь каждая сессия будет держать открытыми равное ему количество курсоров. Курсоры открываются по мере необходимости. В случае, если одно из ваших приложений допускает «утечку курсоров», в конечном итоге ошибка будет возникать при любой величине OPEN_CURSORS, сколь большой бы она не была.

Чтобы понять, подходящее ли значение имеет OPEN_CURSORS, делайте запрос к V$SESSTAT с нахождением максимального значения по «opened cursors current». Если результат окажется близок к величине OPEN_CURSORS, поднимите его значение.

После повышения значения OPEN_CURSORS, по обращению к V$SESSTAT продолжайте наблюдать, сохранится ли рост количества открытых курсоров для любой из ваших сессий. Если у вас для какой-нибудь сессии какого-нибудь приложения рост количества открытых курсоров продолжается после нескольких увеличений значения OPEN_CURSORS, то, скорее всего, код этого приложения допускает утечку курсоров: ваше приложение открывает курсоры и не закрывает их после работы с ними.

Администратору БД ничего делать не нужно – это разработчики приложения должны просмотреть весь код с целью поиска участков, в которых курсоры остаются открытыми, и закрыть их. Всё, что может сделать администратор БД – это выставить значение параметра OPEN_CURSORS очень большим, а также выставить времена, когда сессии приложения будут закрываться и открываться вновь – в качестве временного решения.

Как не сообщать, если вы закрываете все ваши курсоры

К несчастью разработчиков, статистика сессии «opened cursors current» может включать в себя курсоры, которые приложение уже закрыло. Когда код приложения вызывает закрытие курсора, Oracle, на самом деле, помечает курсор как «closeable» [закрываемый]. В действительности курсор может не быть закрытым до тех пор, пока Oracle-у не потребуется место под новый курсор.

Итак, невозможно проверить, закрывает ли приложение все свои курсоры посредством открытия сессии, запуска теста, а затем проверки, упало ли количество открытых курсоров до единицы. Даже если приложение закрывает все свои курсоры надлежащим образом, статистика по «opened cursors current» может показать, что некоторые из «closeable» курсоров до сих пор открыты.

Единственным путём для разработчиков приложений в нашем случае является одиночный запуск теста в специально выделенной для разработки среде с отслеживанием «opened cursors cumulative» в V$SESSTAT для сессии, в которой был запущен тест. Потом выставить значение параметра OPEN_CURSORS в значение немного выше того пикового для открытых курсоров, которое наблюдалось при работе теста, открыть новую сессию и запустить несколько раз тот же самый тест. Если в вашем приложении имеется утечка курсоров, вы увидите растущее значение OPEN_CURSORS [наверное, имелось ввиду значение «opened cursors current»], и после достаточного числа запусков теста вы получите ошибку ORA-01000. (Не выставляйте параметр OPEN_CURSORS слишком низким, иначе он может быть истрачен на рекурсивные SQL-выражения; если ваш одиночный тест открывает очень мало курсоров, рассмотрите возможность продления его работы [видимо, имелось ввиду увеличение количества его запусков] вместо выставления параметра OPEN_CURSORS необоснованно низким.)

Илон Маск рекомендует:  Общие сведения о выделениях (selections)

Мониторинг кэша курсоров сессии

V$SESSTAT также предоставляет статистику количества курсоров, которое имеет каждая сессия в своём кэше курсоров.

Кроме того, вы можете непосредственно видеть, что находится в кэше курсоров сессии запросом к V$ OPEN _ CURSOR . V$ OPEN _ CURSOR предоставляет список кэшированных сессией курсоров с SID и первые несколько символов SQL-предложения с SQL_ID, так что вы можете точно сказать, откуда появляются курсоры.

Настройка SESSION_CA C HED_CURSORS

Если в качестве помощи приложению, которое постоянно закрывает и открывает заново курсоры, вы собираетесь использовать параметр SESSION_CA C HED_CURSORS, то можете отслеживать его эффективность посредством двух статистических показателей в представлении V$SESSTAT. Статистика «session cursor cache hits» отражает количество раз, которое посланное сессией на разбор предложение было обнаружено в кэше курсоров сессии, что означает отсутствие необходимости нового разбора этого предложения и необходимости его поиска в библиотечном кэше. Можете сравнить эту статистику со статистикой «parse count (total)»; вычесть «session cursor cache hits» из «parse count (total)», чтобы узнать количество действительно произведённых разборов.

Отслеживайте эти значения, согласовывая их со статистическим показателем «session cursor cache count».

Если показатель » session cursor cache count » достиг предела, равного значению параметра SESSION_CA C HED_CURSORS, при этом показатель » session cursor cache hits » достаточно низок в сравнении со всеми разборами, и у вас есть подозрение, что приложение повторно отправляет одни и те же запросы на разбор, то увеличение значения параметра SESSION_CA C HED_CURSORS может помочь с конкуренцией за защёлки и дать небольшой выигрыш в производительности. Имейте в виду, что если ваше приложение не отправляет одни и те же запросы на разбор повторно, то » session cursor cache hits » будет оставаться низким, » session cursor cache count » может иметь предельное значение, и кэширование сессией курсоров не поможет вообще. Такое возможно, например, в случае, если ваше приложение использует множество недоступных для совместного использования [unsharable] SQL , тогда повышение значения параметра SESSION_CA C HED_CURSORS ни к чему не приведёт.

Мы осветили разницу между открытыми курсорами и кэшированными сессией курсорами, относящимися к ним параметрами инициализации, как производить их мониторинг и настройку.

Курсоры в Mysql.

/*данные о банке */
CREATE TABLE `bank` (
`Bank >INTEGER (11) NOT NULL ,
`BankName` VARCHAR (50) COLLATE utf8_bin NOT NULL DEFAULT » ,
`Address` VARCHAR (50) COLLATE utf8_bin NOT NULL DEFAULT » ,
`Phone` VARCHAR (50) COLLATE utf8_bin NOT NULL DEFAULT » ,
PRIMARY KEY (`BankId`)

)ENGINE=InnoDB
CHARACTER SET ‘utf8’ COLLATE ‘utf8_bin’ ;
/*данные о вкладах */
CREATE TABLE `bankdistribution` (
`Bank >INTEGER (11) NOT NULL ,
`Persent` INTEGER (11) DEFAULT NULL ,
`ContributeAmount` DECIMAL (10,0) NOT NULL ,
`Client >INTEGER (11) NOT NULL ,
PRIMARY KEY (`BankId`, `ClientId`),
KEY `BankId` (`BankId`),
KEY `ClientId` (`ClientId`),
CONSTRAINT `bankdistribution_fk` FOREIGN KEY (`Bank >REFERENCES `bank` (`BankId`),
CONSTRAINT `bankdistribution_fk1` FOREIGN KEY (`Client >REFERENCES `client` (`ClientId`)
)ENGINE=InnoDB
/*данные о вкладчиках*/
CREATE TABLE `client` (
`Client >INTEGER (3) NOT NULL AUTO_INCREMENT,
`CreditCard >NOT NULL ,
`Surname` VARCHAR (50) COLLATE utf8_bin NOT NULL DEFAULT » ,
`Name` VARCHAR (50) COLLATE utf8_bin NOT NULL DEFAULT » ,
`FirstName` VARCHAR (50) COLLATE utf8_bin NOT NULL DEFAULT » ,
`Phone` VARCHAR (50) COLLATE utf8_bin NOT NULL DEFAULT » ,
`Address` VARCHAR (50) COLLATE utf8_bin NOT NULL DEFAULT » ,
`Safe >INTEGER (5) NOT NULL ,
PRIMARY KEY (`ClientId`, `CreditCardId`),
KEY `ClientId` (`ClientId`)

)ENGINE=InnoDB
AUTO_INCREMENT=11 CHARACTER SET ‘utf8’ COLLATE ‘utf8_bin’

* This source code was highlighted with Source Code Highlighter .

Допустим нам нужно получать по очереди каждый банк и производить с ним какие то действия, помочь в этом нам мог бы такой вот запрос

Select `bank`.* FROM `bank` LIMIT НОМЕР_НУЖНОЙ_НАМ_ЗАПИСИ,1

Begin
/* переменные куда мы извлекаем данные */
Declare vBank >integer ;
Declare vBankName VARCHAR (50);
Declare vAddress VARCHAR (50);
Declare vPhone VARCHAR (50);
/* переменная hadler — a*/
Declare done integer default 0;
/*Объявление курсора*/
Declare BankCursor Cursor for Select `bank`.`Bank >FROM `bank` where 1;
/*HANDLER назначение, которого поясним чуть ниже*/
DECLARE CONTINUE HANDLER FOR SQLSTATE ‘02000’ SET done=1;
/* открытие курсора */
Open BankCursor;
/*извлекаем данные */
WHILE done = 0 DO
FETCH BankCursor INTO vBankId,vBankName,vAddress,vPhone;
делаем нужные нам действия
END WHILE ;
/*закрытие курсора */
Close BankCursor;
END ;

* This source code was highlighted with Source Code Highlighter .

Поясним теперь подробнее. Сначала HANDLER, он нужен для обработки исключения — что делать когда данные закончатся ( то есть курсор будет пустым ). Таким образом когда данные закончатся, не с генерируется сообщение об ошибке, а значение переменной done выставиться в 1, изначально done = 0; подробнее об SQLSTATE читаем тут — dev.mysql.com/doc/refman/5.1/en/error-messages-server.html;

Error: 1329 SQLSTATE: 02000 (ER_SP_FETCH_NO_DATA)

Message: No data — zero rows fetched, selected, or processed

SQLSTATE: 02000 срабатывает когда достигнут конец курсора, или когда select или update возвращяет пустую строку.

Следующей строкой мы объявили курсор DECLARE cursor_name CURSOR FOR select_statement;
Открываем курсор Open cursor_name;
Дальше пока не достигаем конец курсора (WHILE done = 0 DO ) извлекаем данные и обрабатываем их.
Перед выходом из хранимой процедуры необходимо курсор закрыть. Close cursor_name;

Вроде ничего сложного. Но с SQLSTATE ‘02000’ связанно много подводных камней.

WHILE done = 0 DO
FETCH BankCursor INTO vBankId,vBankName,vAddress,vPhone;
/* извлечем для банка сумму любого из его вкладов */
Select (ContributeAmount) INTO vContributeAmountSUM FROM bankdistribution where Bank >limit 1;
делаем какие то действия
END WHILE ;

* This source code was highlighted with Source Code Highlighter .

WHILE done = 0 DO
FETCH BankCursor INTO vBankId,vBankName,vAddress,vPhone;
/* извлечем для банка сумму любого из его вкладов */
Select Сount(ContributeAmount) INTO vContributeAmountSUM FROM bankdistribution where Bank >limit 1;
/* проверим действительно ли есть вклады в этом банке */
if (vContributeAmountSUM > 0) then
/* извлечем для банка сумму любого из его вкладов */
Select ContributeAmount INTO vContributeAmountSUM FROM bankdistribution where Bank >limit 1;
end if ;
делаем какие то действия
END WHILE ;

* This source code was highlighted with Source Code Highlighter .

первым запросом мы проверили а есть ли вклады (если их нет то vContributeAmountSUM == 0 ) и только если таковые имеются мы извлекаем данные.

теперь допустим нам нужно излечь общую сумму на счетах в разных банках у каждого клиента
Declare ClientSummCursor Cursor for Select sum

Declare ClientSummCursor Cursor for Select sum (`bankdistribution`.`ContributeAmount`),`bankdistribution`.`Client >FROM `bankdistribution` Inner Join client on (client.Client >where 1 group by `bankdistribution`.`ClientId`;

Open ClientSummCursor;
WHILE done = 0 DO
FETCH BankCursor INTO vBankId,vBankName,vAddress,vPhone;
/* извлечем для банка сумму любого из его вкладов */
Select Сount(ContributeAmount) INTO vContributeAmountSUM FROM bankdistribution where Bank >limit 1;
/* проверим действительно ли есть вклады в этом банке */
if (vContributeAmountSUM > 0) then
/* извлечем для банка сумму любого из его вкладов */
Select ContributeAmount INTO vContributeAmountSUM FROM bankdistribution where Bank >limit 1;
end if ;
/* извлекаем нужные нам данные */
FETCH ClientSummCursor INTO vSum,vClientId;
делаем какие то действия .
END WHILE ;

* This source code was highlighted with Source Code Highlighter .

может возникнуть та же ситуация, когда данные в курсоре ClientSummCursor, закончатся раньше чем данные в BankCursor, сработает SQLSTATE: 02000, переменная done установится в 1, и цикл while закончиться раньше чем мы ожидали. Этого можно избежать поступив следующим образом

Open ClientSummCursor;
WHILE done = 0 DO
FETCH BankCursor INTO vBankId,vBankName,vAddress,vPhone;
/* извлечем для банка сумму любого из его вкладов */
Select Сount(ContributeAmount) INTO vContributeAmountSUM FROM bankdistribution where Bank >limit 1;
/* проверим действительно ли есть вклады в этом банке */
if (vContributeAmountSUM > 0) then
/* извлечем для банка сумму любого из его вкладов */
Select ContributeAmount INTO vContributeAmountSUM FROM bankdistribution where Bank >limit 1;
end if ;
/* до извлечения данных из второго курсора запомним состояние sqlstate */
SET old_status = done;
/* извлекаем нужные нам данные */
FETCH ClientSummCursor INTO vSum,vClientId;
/* проверяем были ли извлечены данные , не стработал ли sqlstate 0200 */
if (done = 0 ) then
делаем какие то действия .
end if ;
/* перед окончанием while восттановим значение переменной done */
set done = old_status;
END WHILE ;

* This source code was highlighted with Source Code Highlighter .

Всем дочитавшим до этого места спасибо, надеюсь это статься покажется кому то полезной.

ovrimos_cursor

Руководство по PHP
Пред. След.

ovrimos_cursor

(PHP 4 >= 4.0.3, PHP 5)

ovrimos_cursor — Returns the name of the cursor

Description

ovrimos_cursor() returns the name of the cursor. Useful when wishing to perform positioned updates or deletes.

LXXIII. Функции Ovrimos SQL

Ovrimos SQL Server это клиент/серверный транзакционный RDBMS в сочетании с Web-возможностями и быстрыми транзакциями.

Ovrimos SQL Server доступен с www.ovrimos.com. Чтобы включить поддержку в PHP, просто скомпилируйте php с параметром ‘—with-ovrimos’ в скрипте configure. Вам необходимо установить библиотеку sqlcli, имеющуюся в дистрибутиве Ovrimos SQL Server.

Пример 1. Соединение с Ovrimos SQL Server и выбор из системной таблицы

Здесь будет установлено соединение с SQL Server.

Мой блог

понедельник, 14 января 2013 г.

Курсоры в Oracle

Курсор это средство извлечения данных из БД.
Курсоры содержат определения столбцов и объектов.
Курсоры используются для получения строк, возвращаемых запросом.
Для передачи строк в курсор используется запрос, после чего вы можете
выбирать строки из курсора по одной за один раз.

Илон Маск рекомендует:  Лайки Вконтакте что такое и зачем накручивать

create table t1(id, type, text)
as
select object_id, object_type, object_name
from all_objects;

create table t1
as
select object_id id, object_type type, object_name text
from all_objects;

select id, type, text from t1
where >
17367 SCHEDULE FILE_WATCHER_SCHEDULE

select id, type, text from t1
where type = ‘SCHEDULE’;

17364 SCHEDULE DAILY_PURGE_SCHEDULE
17367 SCHEDULE FILE_WATCHER_SCHEDULE
17372 SCHEDULE PMO_DEFERRED_GIDX_MAINT_SCHED
18172 SCHEDULE BSLN_MAINTAIN_STATS_SCHED

Неявные курсоры определяются в момент выполнения:

DECLARE
v_text t1.text%TYPE;

BEGIN
SELECT text INTO v_text
FROM t1
WHERE > DBMS_OUTPUT.PUT_LINE( ‘text = ‘ || v_text );
END;
/

В ходе выполнения кода создается курсор для выборки значения text.

Явный курсор определяется до начала выполнения:

DECLARE
CURSOR c_get_text
IS
SELECT text
FROM t1
WHERE >
v_text t1.text%TYPE;

BEGIN
OPEN c_get_text;
FETCH c_get_text INTO v_text;
DBMS_OUTPUT.PUT_LINE( ‘text = ‘ || v_text );
CLOSE c_get_text;
END;
/

Преимущество явного курсора заключается в наличии у него атрибутов,
облегчающих применение условных операторов.

CREATE OR REPLACE PROCEDURE proc1
AS
CURSOR c_get_text
IS
SELECT text
FROM t1
WHERE >
v_text t1.text%TYPE;

BEGIN
OPEN c_get_text;
FETCH c_get_text INTO v_text;
IF c_get_text%NOTFOUND THEN
DBMS_OUTPUT.PUT_LINE( ‘Данные не найдены. ‘ );
ELSE
DBMS_OUTPUT.PUT_LINE( ‘text = ‘ || v_text );
END IF;
CLOSE c_get_text;
END;
/

А как подобное сделать с неявным курсором:

CREATE OR REPLACE PROCEDURE proc2
AS
v_text t1.text%TYPE;
v_bool BOOLEAN := TRUE;

BEGIN
BEGIN
SELECT text INTO v_text
FROM t1
WHERE >
EXCEPTION
WHEN no_data_found THEN
v_bool := FALSE;
WHEN others THEN
RAISE;
END;

IF NOT v_bool THEN
DBMS_OUTPUT.PUT_LINE( ‘Данные не найдены. ‘ );
ELSE
DBMS_OUTPUT.PUT_LINE( ‘text = ‘ || v_text );
END IF;
END;
/

Пришлось заниматься перехватом исключений, чтобы определить, была ли найдена запись.

Параметризация курсоров помогает повысить степень их повторного использования.

курсор с параметром:

DECLARE
CURSOR c_get_text(par1 NUMBER)
IS
SELECT text
FROM t1
WHERE >
v_text t1.text%TYPE;

BEGIN
OPEN c_get_text(17367);
FETCH c_get_text INTO v_text;
DBMS_OUTPUT.PUT_LINE( ‘text = ‘ || v_text );
CLOSE c_get_text;
END;
/

Переменные типа REF CURSOR могут ссылаться на любые реальные курсоры.
Программа, использующая тип REF CURSOR, может работать с курсорами,
не заботясь о том, какие конкретно данные будут извлечены ими во время выполнения.

CREATE OR REPLACE PROCEDURE proc_ref
AS
v_curs SYS_REFCURSOR;
v_text t1.text%TYPE;

BEGIN
OPEN v_curs
FOR
‘SELECT text ‘
|| ‘FROM t1 ‘
|| ‘WHERE >
FETCH v_curs INTO v_text;

DBMS_OUTPUT.PUT_LINE( ‘text = ‘ || v_text );

Во время компиляции Oracle не знает, каким будет тексе запроса, — он видит строковую переменную.
Но наличие типа REF CURSOR говорит ему о том, что надо будет обеспечить некую работу с курсором.

Например я могу создать функцию, которая принимает некий входной параметр, создает курсор и возвращает тип REF CURSOR :

CREATE OR REPLACE FUNCTION func1(par1 NUMBER)
RETURN SYS_REFCURSOR
IS
v_curs SYS_REFCURSOR;

BEGIN
OPEN v_curs
FOR
‘SELECT text ‘
|| ‘FROM t1 ‘
|| ‘WHERE > || par1;

Другой пользователь может воспользоваться этой функцией так:

v_curs SYS_REFCURSOR;
v_text t1.text%TYPE;

BEGIN
v_curs := func1(17367);

FETCH v_curs INTO v_text;

IF v_curs%NOTFOUND THEN
DBMS_OUTPUT.PUT_LINE( ‘Данные не найдены. ‘ );
ELSE
DBMS_OUTPUT.PUT_LINE( ‘text = ‘ || v_text );
END IF;

Для пользователя, вызывающего функцию func1(), она для него представляет черный ящик, возвращающий курсор.

Сильнотипизированный и слаботипизированный REF CURSOR.

TYPE имя_типа_курсора IS REF CURSOR [ RETURN возвращаемый_тип ];

TYPE refcursor IS REF CURSOR RETURN table1%ROWTYPE;

TYPE refcursor IS REF CURSOR;

Первая форма REF CURSOR называется сильно типизированной, поскольку тип структуры,
возвращаемый курсорной переменной, задается в момент объявления
(непосредственно или путем привязки к типу строки таблицы).

Вторая форма (без предложения RETURN) называется слаботипизированной.
Тип возвращаемой структуры данных для нее не задается.
Такая курсорная переменная обладает большей гибкостью, поскольку для нее можно задавать любые запросы
с любой структурой возвращаемых данных.

В Oracle 9i появился предопределенный слабый тип REF CURSOR с именем SYS_REFCURSOR,
теперь можно не определять собственный слабый тип, достаточно использовать стандартный тип Oracle:

DECLARE
my_cursor SYS_REFCURSOR;

Пример сильнотипизированного курсора:

TYPE my_type_rec IS RECORD (text t1.text%TYPE);
TYPE my_type_cur IS REF CURSOR RETURN my_type_rec;
v_curs my_type_cur;
v_text t1.text%TYPE;

BEGIN
OPEN v_curs
FOR
SELECT text
FROM t1
WHERE >
FETCH v_curs INTO v_text;

DBMS_OUTPUT.PUT_LINE( ‘text = ‘ || v_text );

TYPE my_type_cur IS REF CURSOR RETURN t1%ROWTYPE;
v_curs my_type_cur;
v_var t1%ROWTYPE;

BEGIN
OPEN v_curs
FOR
SELECT *
FROM t1
WHERE >
FETCH v_curs INTO v_var;

Пример слаботипизированного курсора:

TYPE my_type_cur IS REF CURSOR;
v_curs my_type_cur;
v_text t1.text%TYPE;

BEGIN
OPEN v_curs
FOR
SELECT text
FROM t1
WHERE >
FETCH v_curs INTO v_text;

DBMS_OUTPUT.PUT_LINE( ‘text = ‘ || v_text );

v_curs SYS_REFCURSOR;
v_text t1.text%TYPE;

BEGIN
OPEN v_curs
FOR
SELECT text
FROM t1
WHERE >
FETCH v_curs INTO v_text;

DBMS_OUTPUT.PUT_LINE( ‘text = ‘ || v_text );

Курсор можно передавать в качестве параметра:

1. Функция принимающая курсор

CREATE OR REPLACE FUNCTION get_cursor(p_curs SYS_REFCURSOR)
RETURN VARCHAR2
IS
v_text t1.text%TYPE;

FETCH p_curs INTO v_text;

IF p_curs%NOTFOUND THEN
DBMS_OUTPUT.PUT_LINE( ‘Данные не найдены. ‘ );
ELSE
DBMS_OUTPUT.PUT_LINE( ‘Данные найдены. ‘ );
END IF;

2. Процедура принимающая текст SQL

CREATE OR REPLACE PROCEDURE get_sql (p_sql VARCHAR2)
IS
v_curs SYS_REFCURSOR;
v_res VARCHAR2(50);
BEGIN
IF v_curs%ISOPEN THEN
CLOSE v_curs;
END IF;
BEGIN
OPEN v_curs FOR p_sql;
EXCEPTION
WHEN OTHERS THEN
RAISE_APPLICATION_ERROR(-20000, ‘Unable to open cursor’);
END;
v_res := get_cursor(v_curs);
CLOSE v_curs;
DBMS_OUTPUT.PUT_LINE(v_res);
END;
/

BEGIN
get_sql( ‘SELECT text FROM t1 WHERE > END;
/

Данные найдены.
FILE_WATCHER_SCHEDULE

SET SERVEROUTPUT ON

var1 tab.col1%TYPE;
var2 tab.col2%TYPE;
var3 tab.col3%TYPE;

CURSOR cur IS
SELECT col1, col1, col3
FROM tab
ORDER BY col1;

BEGIN
— Открываем курсор

LOOP
— Выбираем из курсора строки
FETCH cur
INTO var1, var2, var3;

EXIT WHEN cur%NOTFOUND;

— Выводим значения переменных
DBMS_OUTPUT.PUT_LINE( ‘col1 = ‘ || var1 || ‘, col2 = ‘ || var2 || ‘, col3 = ‘ || var3 );
END LOOP;

— Закрываем курсор
CLOSE cur;
END;
/

Курсоры и цикл FOR

Для получения доступа к строкам из курсора можно использовать цикл FOR.
При использовании цикла FOR не нужно явно открывать курсор — цикл FOR сделает это автоматически.

SET SERVEROUTPUT ON

CURSOR cur IS
SELECT col1, col1, col3
FROM tab
ORDER BY col1;

BEGIN
FOR var IN cur LOOP
DBMS_OUTPUT.PUT_LINE( ‘col1 = ‘ || var.col1 || ‘, col2 = ‘ || var.col2 || ‘, col3 = ‘ || var.col3 );
END LOOP;
END;
/

Выражение OPEN — FOR

С курсором можно использовать выражение OPEN — FOR, которое добавляет еще больше гибкости при обработке курсоров,
поскольку вы можете назначить курсор для другого запроса.
Запрос может быть любым корректным выражением SELECT.
Это означает что вы можете повторно использовать курсор и назначить курсору позже в коде другой запрос.

SET SERVEROUTPUT ON

— Определим тип REF CURSOR
TYPE t_cur IS
REF CURSOR RETURN tab%ROWTYPE;

— Определим объект типа t_cur
cur t_cur;

— Определим объект для хранения столбцов из таблицы tab
var tab%ROWTYPE;

ovrimos_cursor

Руководство по PHP
Пред. След.

ovrimos_cursor

(PHP 4 >= 4.0.3, PHP 5)

ovrimos_cursor — Returns the name of the cursor

Description

ovrimos_cursor() returns the name of the cursor. Useful when wishing to perform positioned updates or deletes.

Для чего нужна инсинуация cursor for update?

21.10.2014, 18:39

Для чего нужна функция Get?
Помогите пожалуйста, объясните, для чего нужно функция Get unit Unit1; interface .

Для чего нужна строчка
Здравствуйте, объясните пожалуйста, зачем мы пишем строчку: «a.length — 1″я понимаю, что для этого.

Для чего нужна сериализация?
из msdn Сериализация представляет собой процесс преобразования объекта в поток байтов для.

Для чего нужна переменная?
Подскажите, что нам дает переменная f, для чего нужна? #include «stdafx.h» #include .

Для чего нужна строчка?
Помогите разобраться, для чего нужна строчка int count = 1; не совсем понимаю, для чего она тут.

21.10.2014, 20:05 2

FOR UPDATE [OF column_name [. n]]
Определяет обновляемые столбцы в курсоре. Если указано предложение OF column_name [. n], для изменений будут доступны только перечисленные столбцы. Если инструкция UPDATE используется без списка столбцов, то обновление возможно для всех столбцов, за исключением случая, когда был указан параметр параллелизма READ_ONLY.
Курить это еще раз и внимательнее

Добавлено через 4 минуты

22.10.2014, 18:38 [ТС] 3

ApXyC, есть 2 вопроса:
1) for update будет работать только если, поля которые я загрузил в cursor именуются так же в обновлен ой таблице?
2) я всегда обновления с помощью курсора проводил следующим образом: извлекал значения в переменную , в данном случае я бы сделал fetch next from cur into @a,@b , а в условии к update я бы прописали where a=@a and b=@b. Эквивалентен ли мой подход, и не проигрывает ли он update for?

Добавлено через 19 часов 51 минуту
Ответьте плз

Что такое код ovrimos_cursor

Скидка 25% на все тарифы хостинга по промокоду STDCITF

Два критерия профессионализма программирования Oracle: (1) употребление ссылки на курсор в программе

Церковь была отворена, за оградой стояло несколько саней;
по паперти ходили люди.
«Сюда! сюда!» — закричало несколько голосов .

А. С. Пушкин, «Метель»

Аннотация

Рассматриваются ссылки на курсор, представляющие собой инструмент продвинутого программирования в Oracle. Приводятся примеры работы через ссылки на курсор в программах на PL/SQL и Java и в SQL*Plus.

Илон Маск рекомендует:  Что такое код setcbrk

Ссылки на курсор

В пору моего обучения в техническом ВУЗе люди, как и сечас, были склонны называть себя как угодно, и в народе бытовал критерий настоящего математика. Право им назваться отдавалось тому, кто знал, что такое поле Галуа. Таки не ставши математиком, не берусь судить о корректности этого критерия (сдается, он ребяческий), однако занимаясь Oracle, могу предложить другой критерий профессионализма: для программиста этой СУБД.

В диалекте SQL, придуманном фирмой Oracle, есть много разных конструкций, не всякому известных; например, для аналитические функции, или же средства для работы с рукотворными объектами. Но это вещи специфические, не каждому программисту потребные, а вот ссылки на курсор – явление безусловно общего характера.

Ссылка на курсор дает возможность не заводить структуры курсора (CURSOR … IS …) в клиентской программе, а ограничиться в ней выделением памяти только для адреса курсора, в то время как сам курсор будет располагаться целиком в СУБД. Программист способен прожить и без ссылок на курсор, однако те могут дать программам заметные конструктивные выгоды:

  • Они позволяют перенести программную логику на сервер. Клиентские приложения оказываются не так жестко привязаны к конкретным запросам; одни и те же запросы могут вызываться с одинаковым эффектом из программ на PL/SQL, C или Java.
  • Они позволяют перенести вычислительную нагрузку на сервер.

Поскольку принципиально для программирования ссылки на курсоры не нужны, большинство разработчиков обходится обычным способом общения с СУБД. Выгоды же извлекают программисты, которых и можно в данном контексте признать профессионалами.

Ссылки на курсор реализованы в Oracle программно и в SQL. В программе они реализуются в виде специальной переменной, и именно этот вариант показан в этой статье. Клиентскими средами будут выступать PL/SQL, SQL*Plus и Java.

Описание ссылки на курсор и использование в PL/SQL

На каком бы языке вы не общались с БД посредством ссылки на курсор, без программирования на PL/SQL не обойтись. Формальная сторона работы со ссылкой на курсор в PL/SQL обставлена просто.

Во-первых, чтобы завести в PL/SQL переменную-ссылку на курсор, нужно сначала описать ее тип. Это делается в разделе описания с помощью предложения TYPE:

Если конструкция RETURN присутствует, ссылка на курсор называется строгой; если нет – нестрогой. Нестрогая может ссылаться на любой курсор (запрос), а строгая – только на тот, что возвращает результат указанного типа.

Пример описания обоих типов ссылки на курсор:

Открытие курсора с помощью переменной-ссылки на курсор:

Команды FETCH и CLOSE используются как обычно, толькот вместо имени курсора указываем имя ссылки на курсор.

Во-вторых, для удобства программирования поддерживается «системный» тип SYS_REFCURSOR нестрогой ссылки на курсор. Так, в блоке выше, в разделе описания можно было бы не приводить предложение TYPE, а сразу сказать:

Тип SYS_REFCURSOR сокращает текст программы, а иногда позволяет и обойтись без создания служебного пакета (пример чего в этой статье не рассматривается).

Создание пакета в PL/SQL

Приводимые ниже примеры в каждой из трех сред программирования будут использовать для доступа к БД через ссылку на курсор один и тот же пакет. В реальной жизни именно на подобный пакет и ляжет описание требуемой программной логики. Тут же он воимя наглядности устроен максимально просто, (почти) безо всякой программно-прикладной логики, но это обстоятельство и обеспечивает ему универсальность.

Выдадим в SQL*Plus:

В реальной практике такому выхолощенному пакету вполне может найтись свое место, однако часто будут использоваться и другие, общие с приведенным выше только тем, что

(а) в теле будет обязательно присутствовать предложение OPEN

(б) среди параметров должен присутствовать выходной типа ссылки на курсор (возможно строгой).

Остальное регламентируется исключительно логикой приложения и организации программы.

Пример программирования в PL/SQL

В этом примере с помощью нашего пакета открываем курсор и передаем ссылку на курсор в программу. Извлечение результатов предложений SELECT выполняется отдельными процедурами, причем для результатов с разной структурой мы вынуждены предусмотреть разные процедуры извлечения. Это – плата за минимализм и общность пакета.

Выдадим в SQL*Plus:

(Чтобы не усложнять пример, результат на экране почти не оформляется).

Обратим внимание: программам, обрабатывающим по общей схеме однотипные курсоры, мы передаем не тексты запроса, а ссылки на уже открытый и динамически (а не статически, как в случае его определения в отдельном пакете) сформированный курсор.

Пример программирования в SQL*Plus

SQL*Plus позволяет заводить собственные переменные, в том числе и типа нестрогой ссылки на курсор. Открывается курсор, как и в примере выше, нашим пакетом, а вот извлечение возможно обычной командой PRINT. Эта команда умеет распознавать структуру фактического курсора, что очень удобно для работы.

Выдадим в SQL*Plus:

В отличие от предыдущего примера команда PRINT закрывает курсор, так что вторичная выдача

приведет к ошибке.

Пример программирования в Java

В клиентской программе на Java обращаться к БД через ссылку на курсор можно с помощью собственных расширений, сделанных фирмой Oracle в реализации ею драйвера JDBC. В программе ниже предполагается имя СУБД MYDB. Обратите внимание, что текст с запросом SQL передается нашему пакету объектом класса CallableStatement, а извлечение в программу ссылки на курсор делается после приведения этого объекта к сугубо Oracle’овскому классу OracleCallableStatement.

Получение в программу ссылки на курсор соответствует формированию объекта класса ResultSet, обработка которого делается стандартно.

Выдача второго запроса в программе ниже демонстрирует возможность использования одного и того же пакета для получения результата разной структуры. Очевидно, по своей гибкости эта техника находится посередине между тем, что имеется в PL/SQL и в SQL*Plus.

Подготовим файл GenericRefCursor.java:

В ОС оттранслируем класс GenericRefCursor и выполним программу:

Ограничения использования ссылки на курсор

Мысли, возникающие по поводу возможного использования ссылок на курсор в программе, несколько осаждаются существующими ограничениями, часть которых, если вдуматься, имеют свою логику. Как упоминалось, ссылки на курсор не представлены типом SQL (до некоторой степени это естественно), и не могут храниться в качестве переменных пакета PL/SQL. Более полно:

  • ссылки на курсор не могут объявляться как переменные пакета PL/SQL и их нельзя передавать через переменные пакета
  • ссылкам на курсор нельзя присваивать значение NULL (в версии 10 уже можно) и их нельзя сравнивать друг с другом (но их можно присваивать друг другу)
  • ссылки на курсор нельзя хранить в столбцах таблиц и в элементах коллекции
  • ссылки на курсор нельзя передавать от сервера к серверу с помощью RPC
  • ссылки на курсор нельзя использовать с пакетом DBMS_SQL
  • ссылки на курсор не допускают над собой выражений.

PHP » PYTHON

PYTHON ovrimos_cursor

Do you know a Python replacement for PHP’s ovrimos_cursor ? Write it!

PHP ovrimos_cursor

ovrimos_cursor

(PHP 4 >= 4.0.3, PHP 5 ovrimos_cursor — Returns the name of the cursor

Description

Gets the name of the cursor. Useful when wishing to perform positioned updates or deletes.

Parameters

A result identifier, returned by ovrimos_execute() or ovrimos_exec().

Return Values

Returns the name as a string, or FALSE on error.

Ovrimos SQL Функции

Содержание

  • ovrimos_close — Closes the connection to ovrimos
  • ovrimos_commit — Commits the transaction
  • ovrimos_connect — Connect to the specified database
  • ovrimos_cursor — Returns the name of the cursor
  • ovrimos_exec — Executes an SQL statement
  • ovrimos_execute — Executes a prepared SQL statement
  • ovrimos_fetch_into — Fetches a row from the result set
  • ovrimos_fetch_row — Fetches a row from the result set
  • ovrimos_field_len — Returns the length of the output column
  • ovrimos_field_name — Returns the output column name
  • ovrimos_field_num — Returns the (1-based) index of the output column
  • ovrimos_field_type — Returns the type of the output column
  • ovrimos_free_result — Frees the specified result_id
  • ovrimos_longreadlen — Specifies how many bytes are to be retrieved from long datatypes
  • ovrimos_num_fields — Returns the number of columns
  • ovrimos_num_rows — Returns the number of rows affected by update operations
  • ovrimos_prepare — Prepares an SQL statement
  • ovrimos_result_all — Prints the whole result set as an HTML table
  • ovrimos_result — Retrieves the output column
  • ovrimos_rollback — Rolls back the transaction
НОВОСТИ ФОРУМА
Рыцари теории эфира
01.10.2020 — 05:20: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ — Upbringing, Inlightening, Education ->
[center][Youtube]69vJGqDENq4[/Youtube][/center]
[center]14:36[/center]
Osievskii Global News
29 сент. Отправлено 05:20, 01.10.2020 г.’ target=_top>Просвещение от Вячеслава Осиевского — Карим_Хайдаров.
30.09.2020 — 12:51: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ — Upbringing, Inlightening, Education ->
[center][Ok]376309070[/Ok][/center]
[center]11:03[/center] Отправлено 12:51, 30.09.2020 г.’ target=_top>Просвещение от Дэйвида Дюка — Карим_Хайдаров.
30.09.2020 — 11:53: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ — Upbringing, Inlightening, Education ->
[center][Youtube]VVQv1EzDTtY[/Youtube][/center]
[center]10:43[/center]

интервью Раввина Борода https://cursorinfo.co.il/all-news/rav.
мой телеграмм https://t.me/peshekhonovandrei
мой твиттер https://twitter.com/Andrey54708595
мой инстаграм https://www.instagram.com/andreipeshekhonow/

[b]Мой комментарий:
Андрей спрашивает: Краснодарская синагога — это что, военный объект?
— Да, военный, потому что имеет разрешение от Росатома на манипуляции с радиоактивными веществами, а также иными веществами, опасными в отношении массового поражения. Именно это было выявлено группой краснодарцев во главе с Мариной Мелиховой.

[center][Youtube]CLegyQkMkyw[/Youtube][/center]
[center]10:22 [/center]

Доминико Риккарди: Россию ждёт страшное будущее (хотелки ЦРУ):
https://tainy.net/22686-predskazaniya-dominika-rikardi-o-budushhem-rossii-sdelannye-v-2000-godu.html

Завещание Алена Даллеса / Разработка ЦРУ (запрещено к ознакомлению Роскомнадзором = Жид-над-рус-надзором)
http://av-inf.blogspot.com/2013/12/dalles.html

[center][b]Сон разума народа России [/center]

[center][Youtube]CLegyQkMkyw[/Youtube][/center]
[center]10:22 [/center]

Доминико Риккарди: Россию ждёт страшное будущее (хотелки ЦРУ):
https://tainy.net/22686-predskazaniya-dominika-rikardi-o-budushhem-rossii-sdelannye-v-2000-godu.html

Завещание Алена Даллеса / Разработка ЦРУ (запрещено к ознакомлению Роскомнадзором = Жид-над-рус-надзором)
http://av-inf.blogspot.com/2013/12/dalles.html

[center][b]Сон разума народа России [/center]

Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL