теоретический вопрос

mmar
Дата: 19.11.2009 17:03:50
есть система учета времени.. структура очень проста:
table(empid number,time_in date,time_out date)
Есть веб-сервис, через который это все работает. Логика у него тоже простая - смотрим последнюю запись, если time_in и time_out не пустые - инсертим новую строчку, если time_out пустой - делаем update.
Исходя из предположения, что никаких "защит" и "проверок" веб-сервис и клиенты не делают, как обеспечить очередность апдейтов/инсертов. То есть чтоб не было двойных time_in (без time_out).

Заменить select + (update or insert) на merge не получится, так как обновлять нужно поле, по которому определять условие самого обновления. мердж этого не умеет.
Уникальный констрейнт на (empid,time_in) тоже не выглядит надежным.
Интересует вопрос - что еще можно сделать со стороны базы данных чтоб исключить подобные ситуации.. ну и, если кто знает, best practice в таких случаях:)

Спасибо!
hell
Дата: 19.11.2009 17:11:34
mmar


Спасибо!



Думаю, уникальный констрейнт на empid+calculate column nvl(time_out, somebeforedate). Или выпилить null, и использовать там какую-нибудь странную дату.
orawish
Дата: 19.11.2009 17:12:25
mmar,

посмотрите
не уверен за бест, и за то, что вам подойдёт, но это работает
Elic
Дата: 19.11.2009 17:14:45
mmar
чтоб не было двойных time_in (без time_out).
unique(decode(time_out, null, empid))
mmar
Дата: 19.11.2009 18:43:08
hell

Думаю, уникальный констрейнт на empid+calculate column nvl(time_out, somebeforedate). Или выпилить null, и использовать там какую-нибудь странную дату.

да, это понадежней будет чем по (empid,time_in).. я чего-то про индексы не подумал.. констрейнтом же такое условие не задашь..
Elic
mmar
чтоб не было двойных time_in (без time_out).
unique(decode(time_out, null, empid))

по сути, то же самое

orawish, спасибо за ссылку, по-моему немного не то, но обязательно почитаю внимательнее. Таких хитростей с констрейнтами я никогда не делал:)
Elic
Дата: 19.11.2009 18:51:22
mmar
по сути, то же самое
Но гораздо проще и лаконичнее :)
hell
Дата: 20.11.2009 10:55:59
Elic
mmar
по сути, то же самое
Но гораздо проще и лаконичнее :)


Да, декод красивый, как-то я не думал о таком его применении
mmar
Дата: 20.11.2009 11:26:37
ну, на самом деле я сделал по-своему на базе ваших предложений:)
unique (trunc(time_in),empid,decode(time_out,null,--any_constant--))
просто изначально боролся немного не с той проблемой..
Elic
Дата: 20.11.2009 11:30:21
hell
Elic
Но гораздо проще и лаконичнее :)
Да, декод красивый, как-то я не думал о таком его применении
В данном случае можно ещё укоротить, заменив decode на nvl2 :)
Elic
Дата: 20.11.2009 11:45:52
mmar
unique (trunc(time_in),empid,decode(time_out,null,--any_constant--))
Брррр...
Сегодня можно зайти, затем можно выйти, зайти второй раз, но выйти второй раз уже не получится.
К тому же можно заходить каждый день и никогда не выходить.