Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Быстрая проверка существования записи в Oracle


Страницы:   1 2

Ломброзо ©   (2007-03-25 14:19:00) 

Как известно, В MSSQL оператор EXISTS может использоваться как скалярная функция, которая возвращает булевый результат, и её можно использовать для быстрой проверки существования записи по условию, как то:

IF EXISTS(SELECT * FROM CUSTOMERS WHERE NAME = @NAME) THEN ....

В Oracle такая фича не работает и я выкручиваюсь через подсчёт числа записей:


DECLARE
 iCNT NUMBER;
BEGIN
 SELECT COUNT(ID) INTO iCNT FROM CUSTOMERS WHERE NAME = :NAME;
 IF iCNT = 0 THEN ...


Есть ли в оракле какой-нибудь заменитель сей громоздкой конструкции?


evvcom   (2007-03-27 14:45:00) [1]

> [29] ANB ©   (27.03.07 14:32)
> Но неочевидно все все равно.

АбЫдна...

Еще как вариант, по тексту навставлять Step := Step + 1; и в exception запись в лог в том числе и Step. Извращений много разных. :)


ANB   (2007-03-27 14:32:00) [2]


> А 10-ку на этот счет не тестил пока.

Я тестил. Тока теперь там еще одну функцию добавили для выгребания стека. Разобраться, что сломалось, помудохавшись, можно. Но неочевидно все все равно.


evvcom   (2007-03-27 14:22:00) [3]

> [27] ANB ©   (27.03.07 12:01)
> И так обернуть каждый оператор ?

А это уж, как душе угодно. :)

> А вот обработка исключений в оракле имеет некоторые проблемы,
> т.к. до 10-ки при перехвате их портился стек ошибок. И
> разобраться, где именно произошли проблемы, довольно тяжело.

Вот, видимо, из-за этого и родилась у меня такая идея. А 10-ку на этот счет не тестил пока.


ANB   (2007-03-27 12:01:00) [4]


> evvcom ©   (27.03.07 10:36) [26]

И так обернуть каждый оператор ?

Предварительные проверки, имхо, имеют смысл именно из-за простоты их реализации. Но база все равно должна быть закрыта от мусора ограничениями.

А вот обработка исключений в оракле имеет некоторые проблемы, т.к. до 10-ки при перехвате их портился стек ошибок. И разобраться, где именно произошли проблемы, довольно тяжело.


evvcom   (2007-03-27 10:36:00) [5]

> [23] Ломброзо ©   (27.03.07 00:18)
> мне ничего не говорит о том, по какой причине и в каком
> месте случилась ошибка

а кто тебе мешает написать:
<procedure>
begin
 ...
 begin
   ...
 exception
   ...
 end;
 ...
 begin
   ...
 exception
   ...
 end;
 ...
 begin
   ...
 exception
   ...
 end;
 ...
exception
 ...
end;
Будет тебе и место и смысл


Ломброзо   (2007-03-27 01:27:00) [6]

Да ладно, select for update я уже освоил на твёрдую тройку и запытал в конкурирующей среде :) Вполне устраивает.


Petr V. Abramov   (2007-03-27 00:40:00) [7]

> Не боинг, но всё же.
так бы и ветку озаглавил, хрен вас медиков, поймешь, спросишь в реанимации анекдот, так говорят: "у нас все про покойников" :)))) увы, из жизни....

> Ломброзо ©
че те не устаривает в стандартном подходе Oracle? щас объясним, че ты в нем не понимаешь или workaround придумаем.


Ломброзо   (2007-03-27 00:18:00) [8]

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

Вот такой код (с)


when others then
if sqlcode = 1 then
  -- тут в автономной транзакции запиши куда-нить оригинальный sqlerrm
  raise_application_error(-2001, 'сам дурак и никаких имен таблиц' );
else
  raise;
end if;


- мне ничего не говорит о том, по какой причине и в каком месте случилась ошибка, если отключить Debug info и не смотреть стек.

Разумеется, в проверке тех предусловий, которые проверяются в том числе и констрейнтами, ручками, есть некоторое неудобство, но тут предметная область такая. Не боинг, но всё же.


Petr V. Abramov   (2007-03-26 23:31:00) [9]

имелось в виду, когда констрайнта нет и он моделируется кодом, что стронгли не рекомендуется в документации.


Petr V. Abramov   (2007-03-26 23:15:00) [10]

> ANB ©   (26.03.07 17:11) [17]
> А в 10% сработает констрайнт. При чем тут random
если есть констрайнт, то получим исключение по факту инсерта. хоть и проверяли, что "нету".
будут и более гадкие ситуациии, при delete в другой транзакции, без exception

> А в 10% сработает констрайнт. При чем тут random
а нахрена писанина, если все ошибочные ситуации этими "10%" и описываются?


Val   (2007-03-26 18:23:00) [11]

я, наверное.


ANB   (2007-03-26 18:20:00) [12]


> "незначительной" разницы между блокировочником и версионником

Эээ. А кто тут версионник ? Про IB/FB разговора вроде не было . . .


Val   (2007-03-26 18:09:00) [13]

Честно говоря, я бы попытался сделать вставку и обработать исключение, а не выборку, а затем обработку условия и вставку, которая может не произойти по вышеописанным причинам.
p.s. топик возник, думается, как тут говорили, из-за "незначительной" разницы между блокировочником и версионником ;)


ANB   (2007-03-26 17:11:00) [14]


> Petr V. Abramov ©   (26.03.07 13:51) [16]

А в 10% сработает констрайнт. При чем тут random ?


Petr V. Abramov   (2007-03-26 13:51:00) [15]

> минимум 90% случаев они обрабатывают.
тогда можно не писать никаких проверок, а проверять резльтат random.


ANB   (2007-03-26 13:05:00) [16]

Практически все проверки, выполняемые до DML могут оказаться ложными к моменту собственно изменения данных. Что, однако, не снижает их полезности, т.к. минимум 90% случаев они обрабатывают.
Вывод - если операция не критична по скорости и не лень эти проверки писать - то есть смысл таки их написать. Но при этом не забывать об ограничениях.
Все имхо.


evvcom   (2007-03-26 12:06:00) [17]

А что после
> IF iCNT = 0 THEN ...
? От этого зависит красота решения. А то "вставят, не вставят" :) Каков вообще смысл проверки?


Evgeny V   (2007-03-26 09:38:00) [18]


> roottim ©   (26.03.07 09:20) [12]

Добавить INTO и перевести в PL/SQL не проблема думаю
Ну если надо строго 1 или 0, то можно и такие варианты

Первый с COUNT, хоть и COUNT, но считать не более одной записи...

SELECT COUNT(*) from (SELECT 1   FROM dual where exists(select sernum from myshema.avl_sensor where dk > SYSDATE-1))

Второй вариант

select nvl(
(select 1 from adm.avl_sensor
where dk > SYSDATE-1
and rownum<=1),0) from dual


roottim   (2007-03-26 09:20:00) [19]

у тебя нет into, речь ведь о pl/sql
а посему влетит exception no_data_found который обработать надо...
посему тот же результат без гемороя можно получить обернув его
select
 nvl((SELECT 1 FROM dual where exists(select 1 from myshema.avl_sensor where dk > SYSDATE-1), 0) f_exists
into
 v_result
from
 dual


Evgeny V   (2007-03-26 07:48:00) [20]

В Оракле например -
SELECT 1   FROM dual where exists(select sernum from myshema.avl_sensor where dk > SYSDATE-1)

Есть запись - получим 1, нет -получим NULL

В свое время узнал это от Шевченко Игоря и Внука:-)


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо