четверг, 14 июня 2007 г.

Нет в Oracle exists

Нет в оракле конструкции exists в pl/sql, подобной той, что есть в Firebird/Interbase
if exists(select..) then
приходится извращаться через:
select count(1) into from table where rownum=1
EXCEPTION WHEN NO_DATA_FOUND THEN
code;

Надеюсь rownum=1 дает хоть какой-то выигрыш в скорости(exists достаточно быстрая операция, в отличии от count).

PS
Прикольно - казалось бы логичное ограничение в rownum=1, может сработать не всегда - когда таблица партиционирована, используется каунт и включен параллелизм - может идти фуллскан по всей таблице. Горе от ума, что говорится.
Правда до версии 10g r1 (Relevant for Oracle until 10g r1)
"Selecting ROWNUM = 1 with 100.000 PIO"
http://www.db-nemec.com/Selecting_ROWNUM_1.html

5 комментариев:

Unknown комментирует...

Можно извратиться к примеру так:
BEGIN
FOR i IN (SELECT * FROM dual WHERE EXISTS(Ваш_запрос)) LOOP
dbms_output.put_line('Exists');
END LOOP;
END;
/

Единственный минус - открытие курсора, хотя не так то это и тяжко для БД. Не очень красиво, но все же... один проход по циклу получается, так что один хрен, что FOR..LOOP, что IF..THEN

pnv82 комментирует...

Вариант конечно, но курсор...

Unknown комментирует...

что-то мне подсказывает, что в IF..THEN тоже неявно будет открыт курсор, но время его жизни будет короче, т.е. только при проверке условия, в FOR..LOOP он будет открыт до END LOOP.

pnv82 комментирует...

Тогда я не понял касательно IF THEN - какой в Oracle есть вариант с такой конструкцией?
В том варианте, что я привел(в нем кстати ошибка - count естественно нельзя использовать) - курсоров, насколько я понимаю, не открывается, так ведь?

Unknown комментирует...

Верно, тоже прозевал...
Тогда уж, если с IF..THEN и COUNT заморачиваться, то стоит ввести отдельную переменную, сделать "select count(*) into переменная from table", а потом ее уже сравнивать с нулем. В данном случае 100% откроется курсор :)
Так что для сокращения объема кода можно использоват именно FOR..LOOP, но для читабельности стоит использовать считывание в переменную и далее IF