Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.12.28;
Скачать: CL | DM;

Вниз

UPDATE / INSERT в одном флаконе   Найти похожие ветки 

 
Добегался...   (2008-09-30 12:38) [0]

Частенько появляется необходимость сделать UPDATE / INSERT в зависимости от наличия записи по PK.

То есть, существует набор полей. Их нужно записать в БД, причем если запись с такой ID есть - то обновить ее, если ее нету - то создать.

Кто как делает? Предварительный SELECT - потом по его результатам? Или сначала делаем INSERT, а в случае исключения делаем UPDATE?
Или это конкретно зависит от базы данных (например, в SQLite вроде никакого исключения не делается, если сделать INSERT с существующим PK, просто запись не вставится).

В частности, интересует SQLite и Firebird. Но также любопытно как это делают в других БД аля oracle / MSSQL.

P.S. Я так понимаю при рассмотрении вопрос переплетается с вариантами синхронизации баз данных. Это тоже интересно, как делается синхронизация, как БД узнает какие записи синхронизировать, чисто по полю "последнее время обновления" или еще как? Ну вкратце, чтобы ориентироваться, серьезно изучать вопрос пока не могу.


 
tesseract ©   (2008-09-30 12:53) [1]

Хранимка ? c проверкой на exists ?


 
KSergey ©   (2008-09-30 12:54) [2]

Я думаю так: если не понятно что делать insert или update - тут с логикой постоение что-то не так.
Что же до синхронизации - то планирую сделать явнфми флажками (или луче параллельной таблицей с тем же PK флажками "уже обновлено"). Флажки сбрасывать триггером в основной таблице при модификациях.


 
oldman ©   (2008-09-30 12:54) [3]

Можно еще поле завести. Логическое.
true - update, false - insert.

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


 
KSergey ©   (2008-09-30 12:55) [4]

> или луче параллельной таблицей с тем же PK флажками

или луче параллельной таблицей с тем же PK и флажками


 
Ega23 ©   (2008-09-30 12:57) [5]


> Кто как делает?


Хранимка с if exists


 
Ega23 ©   (2008-09-30 12:57) [6]

А вообще - согласен с

> Я думаю так: если не понятно что делать insert или update
> - тут с логикой постоение что-то не так.


 
clickmaker ©   (2008-09-30 12:59) [7]

if @Id > 0
 update
else
 insert


 
Ega23 ©   (2008-09-30 13:00) [8]


> clickmaker ©   (30.09.08 12:59) [7]


Ага, я такое постоянно использую. Но, как я понимаю, это не совсем то, что хочет автор...


 
Polevi ©   (2008-09-30 13:04) [9]

http://msdn.microsoft.com/en-us/library/bb510625.aspx


 
Johnmen ©   (2008-09-30 13:12) [10]

http://www.ibase.ru/devinfo/testiu.htm


 
Anatoly Podgoretsky ©   (2008-09-30 13:34) [11]

> Добегался...  (30.09.2008 12:38:00)  [0]

Удалять можно, тогда DELETE + INSERT


 
b z   (2008-09-30 13:40) [12]


> серьезно изучать вопрос пока не могу.
А стоит ли не серьезно его изучать? :)


 
clickmaker ©   (2008-09-30 13:42) [13]

> Удалять можно, тогда DELETE + INSERT

в чужом пхпэшном коде как-то наткнулся на такое. Долго думал, почему так, а не через update. Так и не додумался, переписал нафик )


 
oldman ©   (2008-09-30 13:46) [14]


> clickmaker ©   (30.09.08 13:42) [13]
>  Так и не додумался, переписал нафик )


Работало?
"Ничего руками не трогай!" ©


 
GlFox ©   (2008-09-30 14:09) [15]

Делаю так:update or insert into Table1(ID,NAME) values(?,?)
Читаю здесь: http://www.firebirdsql.org/rlsnotesh/rlsnotes210.html#rnfb210-updorinsrt


 
Игорь Шевченко ©   (2008-09-30 14:42) [16]

в oracle используется merge


 
oldman ©   (2008-09-30 14:47) [17]

table1.first
while not eof do begin
 i:=id
 if locate(id, table2) then update else insert
 table1.next
end;

:)))
зы: за синтаксис не пинайте...


 
Dmitry S ©   (2008-09-30 14:59) [18]

Жаль MySQL нету в списке. Там это делается
REPLACE INTO


 
KygECHuK ©   (2008-09-30 15:03) [19]


> [17]

Это как напильником пилить дерево...
какой уж там синтаксис....


 
MsGuns ©   (2008-09-30 15:04) [20]

>зы: за синтаксис не пинайте...

Будем пинать за логику, точнее за ее отсутствие. А также за абсолютно не рабочий код
:)


 
Городской Шаман   (2008-09-30 15:10) [21]


> Добегался...   (30.09.08 12:38)  


Я длоя этого написал мини ORM движок с наличием хелперов(динамическая вставка и обновление полей объекта в зависимости от изменения в них данных). Писал два дня, думал две недели...


 
Раиса ©   (2008-09-30 15:18) [22]

Добегался...   (30.09.08 12:38)  
сначала делаем INSERT, а в случае исключения делаем UPDATE

1.Я так иногда делаю (MS SQL).

Anatoly Podgoretsky ©   (30.09.08 13:34) [11]
Удалять можно, тогда DELETE + INSERT


2.И такое тоже практикуется чаще, чем первый вариант. (MS SQL, MySQL).


 
oldman ©   (2008-09-30 15:22) [23]


> KygECHuK ©   (30.09.08 15:03) [19]
>
> > [17]
>
> Это как напильником пилить дерево...


Нахлынуло просто.
Dbase, Fox, Clipper...
Решать проблему тупо и в лоб!


 
Anatoly Podgoretsky ©   (2008-09-30 15:29) [24]

> clickmaker  (30.09.2008 13:42:13)  [13]

update = DELETE + INSERT и по сути тоже. Только триггера мешаются, но в чистом SQL это именно так.


 
Anatoly Podgoretsky ©   (2008-09-30 15:31) [25]


> в oracle используется merge

Включат в стандарт или хотя бы в реализацию сервера, то же будем, но по сути это извращение.


 
tesseract ©   (2008-09-30 15:45) [26]


> update = DELETE + INSERT и по сути тоже.


Вах. Зависит от базы. Например на некторых Delete такая процедура, что лучше её не выполнять.


 
Игорь Шевченко ©   (2008-09-30 15:50) [27]

tesseract ©   (30.09.08 15:45) [26]


> Вах. Зависит от базы.


Ты можешь предложить другой способ ?


 
oldman ©   (2008-09-30 15:55) [28]


> tesseract ©   (30.09.08 15:45) [26]
> > update = DELETE + INSERT и по сути тоже.
> Вах. Зависит от базы.
>
> Игорь Шевченко ©   (30.09.08 15:50) [27]
> Ты можешь предложить другой способ ?


Игорь, а что замена значения полей равно delete+insert?
Для значения - да. Для записи - таки нет!


 
Anatoly Podgoretsky ©   (2008-09-30 16:27) [29]

> tesseract  (30.09.2008 15:45:26)  [26]

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


 
tesseract ©   (2008-09-30 16:39) [30]


> Игорь, а что замена значения полей равно delete+insert?


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


 
Игорь Шевченко ©   (2008-09-30 17:39) [31]


> Игорь, а что замена значения полей равно delete+insert?


В большинстве случаев да. Потому что при замене значений полей заменяется запись целиком


 
Vlad Oshin ©   (2008-09-30 17:47) [32]


>  замена значения полей равно delete+insert?

а ID записи?


 
Anatoly Podgoretsky ©   (2008-09-30 19:42) [33]

> Vlad Oshin  (30.09.2008 17:47:32)  [32]

А что ИД записи?


 
Раиса ©   (2008-09-30 20:11) [34]


> Anatoly Podgoretsky ©   (30.09.08 19:42) [33]


ИД записи поменяется (хотя не знаю, кому это принципиально).


 
Раиса ©   (2008-09-30 20:11) [35]

Удалено модератором


 
Johnmen ©   (2008-09-30 20:40) [36]


> Раиса ©   (30.09.08 20:11) [34]
> ИД записи поменяется

Это про какой сервер речь?


 
Johnmen ©   (2008-09-30 20:40) [37]

Удалено модератором


 
Anatoly Podgoretsky ©   (2008-09-30 21:01) [38]

> Раиса  (30.09.2008 20:11:34)  [34]

Зачем тогда выбраны изменяемые ИД, если важна их неизмеяемость?


 
Anatoly Podgoretsky ©   (2008-09-30 21:02) [39]

Мы с Тамарой ходим парой.


 
Добежал   (2008-10-27 11:01) [40]

>Делаю так:update or insert into Table1(ID,NAME) values(?,?)

а по какому условию тогда сработает update?!


 
Petr V. Abramov ©   (2008-10-27 11:07) [41]


> Игорь Шевченко ©   (30.09.08 17:39) [31]
>
> > Игорь, а что замена значения полей равно delete+insert?
>
>
>
> В большинстве случаев да. Потому что при замене значений
> полей заменяется запись целиком


в большинстве случаев нет.
на оракле по крайней мере


 
jack128_   (2008-10-27 11:18) [42]


> а по какому условию тогда сработает update?!

а ведь тебе даже ссылку дали на документацию...


 
Ega23 ©   (2008-10-27 11:43) [43]

В целом, Update выполняется как Delete + Insert.
Но, AFAIK, не вызываются триггеры на вставку-удаление


 
isasa ©   (2008-10-27 12:12) [44]

?

UPDATE ....
IF SQL%ROWCOUNT=0 THEN
   INSERT ...
END IF;


 
blackman ©   (2008-10-27 12:13) [45]

Всегда Replace и будет счастье :)


 
Petr V. Abramov ©   (2008-10-27 12:29) [46]


> isasa ©   (27.10.08 12:12) [44]

а пока выполнялся if, другая транзакция вставила запись...


 
Правильный$Вася   (2008-10-27 13:20) [47]


> update = DELETE + INSERT и по сути тоже

это если нет FOREIGN KEY, ссылающихся на эту запись, и не включен режим отложенной проверки ограничений


 
Ega23 ©   (2008-10-27 13:26) [48]


> это если нет FOREIGN KEY, ссылающихся на эту запись, и не
> включен режим отложенной проверки ограничений


Это без разницы. Наглядный пример - триггер на Update. Нет таблицы Updated, есть Inserted и Deleted.


 
Petr V. Abramov ©   (2008-10-27 13:36) [49]


>  Нет таблицы Updated, есть Inserted и Deleted.

я уверен, что это сделано просто для удобства разработчика, чтоб был доступ к старым и новым значениям, не перегружая t-sql, и к физической реализации update отношения не имеет


 
Ega23 ©   (2008-10-27 13:45) [50]


> я уверен, что это сделано просто для удобства разработчика,
>  чтоб был доступ к старым и новым значениям, не перегружая
> t-sql, и к физической реализации update отношения не имеет
>


Я предлагаю данный вопрос обсудить не тут а в подобающем месте. :)))


 
speller   (2008-10-27 14:14) [51]


> В теории это одно и тоже

а если делается апдейт не всех полей, а только одного? тоже удалять всю запись?


 
isasa ©   (2008-10-27 14:39) [52]

Petr V. Abramov ©   (27.10.08 12:29) [46]

а пока выполнялся if, другая транзакция вставила запись...


А кто мешает выполнять эту хранимую процедуру с клиента в одной транзакции?


 
isasa ©   (2008-10-27 14:42) [53]

ЗЫ. Как бы ты не извращался, а если два или более оператора, то придется делать так. Что бы не случилось так, как ты писал ....


 
Правильный$Вася   (2008-10-27 15:25) [54]


> Ega23 ©   (27.10.08 13:26) [48]
> > это если нет FOREIGN KEY, ссылающихся на эту запись, и  не
> > включен режим отложенной проверки ограничений
> Это без разницы. Наглядный пример - триггер на Update. Нет таблицы
> Updated, есть Inserted и Deleted.

1. это лишь способ представления
2. это частный подход одной из СУБД


 
Anatoly Podgoretsky ©   (2008-10-27 15:34) [55]

> speller  (27.10.2008 14:14:51)  [51]

Так оно так и делается, в транзакции, создается новая запись, а старая удаляется (помечается как свободная).


 
Anatoly Podgoretsky ©   (2008-10-27 15:35) [56]

> Правильный$Вася  (27.10.2008 15:25:54)  [54]

Ну и что, что частный случай, ну в других есть .old .new точно также две записи одновременно. Подумаешь по другому назвали.


 
Правильный$Вася   (2008-10-27 15:56) [57]


> ну в других есть .old .new точно также две записи одновременно.
>  Подумаешь по другому назвали.

это не 2 записи, это 2 состояния одной записи, при этом запись не пропадает (как в случае delete-insert), а переходит из одного состояния в другое


 
Petr V.Abramov   (2008-10-27 16:06) [58]


> isasa ©   (27.10.08 12:12) [44]
> ?
>
> UPDATE ....
> IF SQL%ROWCOUNT=0 THEN
>    INSERT ...
> END IF;



> isasa ©   (27.10.08 14:39) [52]
> Petr V. Abramov ©   (27.10.08 12:29) [46]
>
> а пока выполнялся if, другая транзакция вставила запись.
> ..
>
> А кто мешает выполнять эту хранимую процедуру с клиента
> в одной транзакции?


а какая разница, pl/sql-блок (пофиг, хранимый или анонимный) не в критической же секции выполняется, после update процесс запросто могут усыпить, и другая транзакция, пока он спит, полбазы переделает.
Вполне реальная ситуация, хоть и кажется, что вероятность маленькая, законы Мерфи имеют приоритет над законами боьших чисел.


 
Petr V.Abramov   (2008-10-27 16:07) [59]


> isasa ©   (27.10.08 14:42) [53]
> ЗЫ. Как бы ты не извращался, а если два или более оператора,
>  то придется делать так. Что бы не случилось так, как ты
> писал ....

не забыв че-нить заблокировать, что конкретно - по ситуации


 
Petr V.Abramov   (2008-10-27 16:08) [60]


> Ega23 ©   (27.10.08 13:45) [50]

ну вообще вопрос важный :)


 
Ega23 ©   (2008-10-27 16:18) [61]


> ну вообще вопрос важный :)


Главное - сирьйозный.


 
Ega23 ©   (2008-10-27 17:14) [62]


> ну вообще вопрос важный :)


Ну дык как, обсудим сегодня?


 
Правильный$Вася   (2008-10-27 17:25) [63]


> Ну дык как, обсудим сегодня?

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



Страницы: 1 2 вся ветка

Текущий архив: 2008.12.28;
Скачать: CL | DM;

Наверх




Память: 0.62 MB
Время: 0.015 c
2-1226839134
Kawun
2008-11-16 15:38
2008.12.28
Получить массив и подсчитать его элементы. (+ см.тему)


2-1226831140
ИванН
2008-11-16 13:25
2008.12.28
TListBox + прокрутка


2-1227004020
Apachi
2008-11-18 13:27
2008.12.28
Создание одной переменной несколько объектов


15-1225078325
Slider007
2008-10-27 06:32
2008.12.28
С днем рождения ! 26 октября 2008 воскресенье


15-1222763889
Добегался...
2008-09-30 12:38
2008.12.28
UPDATE / INSERT в одном флаконе