Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 @@ROWCOUNT и Exists  [new]
Darooma
Member

Откуда:
Сообщений: 758
Есть таблица CustomerStores (CustomerId, StoreId), которая связывает связью "многие-ко-многим" 2 таблицы. Первичного ключа у нее нет. Нужно добавть запись в эту таблицу, но только в том случае, если ее там нет.

Есть 2 варианта

if not exists (
  select top 1 from CustomerStores where CustomerId=@CustomerId and StoreId=@StoreId)
insert into ....
и

update CustomerStores 
set CustomerId=@CustomerId and StoreId=@StoreId
where CustomerId=@CustomerId and StoreId=@StoreId
if @@ROWCOUNT = 0
inset into ....

Какой вариант более рационален и логичен?
10 июн 11, 14:32    [10796453]     Ответить | Цитировать Сообщить модератору
 Re: @@ROWCOUNT и Exists  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
Darooma,

я чесс говоря второй вараинт вообще не понял..зачем апдейтить-то? обычной выборкой на экзистс как-то логичнее, как в первом варианте... только топ можно убрать, сервер и так не дурак =)
кстати, что мешает сделать составной ключ по двум полям, чтобы обеспечить целостность данных?
10 июн 11, 14:36    [10796507]     Ответить | Цитировать Сообщить модератору
 Re: @@ROWCOUNT и Exists  [new]
ura
Member [заблокирован]

Откуда: Киев
Сообщений: 932
insert into ....
where not exists(select *...)
10 июн 11, 14:58    [10796783]     Ответить | Цитировать Сообщить модератору
 Re: @@ROWCOUNT и Exists  [new]
Darooma
Member

Откуда:
Сообщений: 758
ura,

тоже вариант.
Как насчет concurrency? Оно может случится в этом примере?
10 июн 11, 15:13    [10796975]     Ответить | Цитировать Сообщить модератору
 Re: @@ROWCOUNT и Exists  [new]
Shlippenbaranus
Member

Откуда:
Сообщений: 241
Darooma
ura,

тоже вариант.
Как насчет concurrency? Оно может случится в этом примере?


Какая версия MS SQL? В 2008, насколько я знаю, уже появилась конструкция merge. Как раз подходит для такой задачи.
10 июн 11, 15:24    [10797084]     Ответить | Цитировать Сообщить модератору
 Re: @@ROWCOUNT и Exists  [new]
Darooma
Member

Откуда:
Сообщений: 758
Shlippenbaranus
Darooma
ura,

тоже вариант.
Как насчет concurrency? Оно может случится в этом примере?


Какая версия MS SQL? В 2008, насколько я знаю, уже появилась конструкция merge. Как раз подходит для такой задачи.

2008.
что это за инструкция?
10 июн 11, 15:28    [10797134]     Ответить | Цитировать Сообщить модератору
 Re: @@ROWCOUNT и Exists  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31984
Darooma
Shlippenbaranus
Какая версия MS SQL? В 2008, насколько я знаю, уже появилась конструкция merge. Как раз подходит для такой задачи.

2008.
что это за инструкция?
Так и называется - MERGE
10 июн 11, 15:30    [10797151]     Ответить | Цитировать Сообщить модератору
 Re: @@ROWCOUNT и Exists  [new]
Darooma
Member

Откуда:
Сообщений: 758
alexeyvg
Darooma
пропущено...

2008.
что это за инструкция?
Так и называется - MERGE

Я имею ввиду как ее применить к моему примеру?
10 июн 11, 15:31    [10797171]     Ответить | Цитировать Сообщить модератору
 Re: @@ROWCOUNT и Exists  [new]
Shlippenbaranus
Member

Откуда:
Сообщений: 241
SomewhereSomehow
я чесс говоря второй вараинт вообще не понял..зачем апдейтить-то?


Ну, это есть стандартная задача - проапдейтить строку, если она существует, или вставить новую строку, если не существует. Такой себе "параметрический счетчик". Используется, например, для подсчета какой-нибудь суммы помесячно. В начале каждого месяца нужно заводить новую строку, а потом ее обновлять. При этом нужно следить, чтобы строка для какого-то месяца не завелась два раза.
10 июн 11, 15:33    [10797187]     Ответить | Цитировать Сообщить модератору
 Re: @@ROWCOUNT и Exists  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
Shlippenbaranus,

Darooma
Есть таблица CustomerStores (CustomerId, StoreId), которая связывает связью "многие-ко-многим" 2 таблицы. Первичного ключа у нее нет. Нужно добавть запись в эту таблицу, но только в том случае, если ее там нет.


я что-то ни разу не вижу здесь ни слова про то, что надо обновить запись. Да и что обновлять-то...значение на само себя же? и мердж здесь, имхо, тоже наифиг не нужен. обычный контроль вставки дубликатов...проверяем наличие и добавляем.
10 июн 11, 15:40    [10797289]     Ответить | Цитировать Сообщить модератору
 Re: @@ROWCOUNT и Exists  [new]
Shlippenbaranus
Member

Откуда:
Сообщений: 241
SomewhereSomehow
Shlippenbaranus,

Darooma
Есть таблица CustomerStores (CustomerId, StoreId), которая связывает связью "многие-ко-многим" 2 таблицы. Первичного ключа у нее нет. Нужно добавть запись в эту таблицу, но только в том случае, если ее там нет.


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


Я думаю, топикстартер строил условный пример, и малость недоговорил :). Но если я ошибся - приношу извинения.
10 июн 11, 15:44    [10797334]     Ответить | Цитировать Сообщить модератору
 Re: @@ROWCOUNT и Exists  [new]
Darooma
Member

Откуда:
Сообщений: 758
SomewhereSomehow,

какой твой вариант для проверки? Я придерживаюсь where not exists.

НО! Ведь нужно еще учитывать, что нужно еще и удалять ненужные магазины (store) у клиента (customer).

Например, было у клиента 5 магазинов, он на странице удалил 2. Теперь у него осталось 3. Получается, что при каждом обновлении нужно удалять все магазины для данного клиента и заново добавлять их из массива, который пришел на вход. И все это за один batch.
10 июн 11, 15:46    [10797353]     Ответить | Цитировать Сообщить модератору
 Re: @@ROWCOUNT и Exists  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
Darooma,

я уже привел его выше...

вы же скрываете условия, люди угадайством занимаются, обновлять вам что-то предлагают, а вы тут бац и всех обломали, оказывается удалять надо еще! =)
Вас что конкретно беспокоит? Способ? так ведь вы не говорите как у вас организовано общение с клиентом..

Вот очередная угадайка (как вы и просили с мердж-ем):

допустим у вас в процедуру с клиента передается табличный параметр, в котором содержатся связи и действия которые над этими свзями произвел клиент, например какие-то магазины добавил, какие-то удалил, и отправил на сервер - вам теперь требуется отразить это в бд:
use tempdb;
go
create table CustomerStores (CustomerId int, StoreId int)
insert into CustomerStores values (1,1),(1,2),(2,3),(2,4)
go
declare @CustomerStores table (CustomerId int, StoreId int, act char(1))
insert into @CustomerStores
values (1,2,'D'),(1,5,'I'),(2,4,'D'),(2,5,'I')
--I - inserted, D - deleted

merge into 
	CustomerStores cs
using 
	(select CustomerId, StoreId, act from @CustomerStores) i on 
	i.CustomerId = cs.CustomerId and i.StoreId = cs.StoreId
when 
	matched and i.act = 'D' then delete
when 
	not matched and i.act = 'I' then insert (CustomerID, StoreID) values (i.CustomerID, i.StoreID);

select * from CustomerStores
go
drop table CustomerStores
особо не проверял..как пример.
а вот если у вас например на каждое действие с клиента отправляется запрос на сервер - то и запросы будут другие, на добавление просто проверяйте дубль как советовали выше, на удаление - удаляйте соответсвенно...
10 июн 11, 16:13    [10797687]     Ответить | Цитировать Сообщить модератору
 Re: @@ROWCOUNT и Exists  [new]
Darooma
Member

Откуда:
Сообщений: 758
SomewhereSomehow,

хороший пример. Пока требования таковы, что удаление и добавление и изменение (данных о store) происходит на одной странице - на странице редактирования. Спасибо.
10 июн 11, 16:22    [10797788]     Ответить | Цитировать Сообщить модератору
 Re: @@ROWCOUNT и Exists  [new]
Darooma
Member

Откуда:
Сообщений: 758
SomewhereSomehow,

Я не пойму, как можно данный код переделать в процедуру? Какие параметры она будет принимать?
10 июн 11, 16:25    [10797815]     Ответить | Цитировать Сообщить модератору
 Re: @@ROWCOUNT и Exists  [new]
invm
Member

Откуда: Москва
Сообщений: 9838
Необходимо еще учесть, что если в целевой таблице есть рулсы, то использовать merge не получится.
10 июн 11, 16:34    [10797908]     Ответить | Цитировать Сообщить модератору
 Re: @@ROWCOUNT и Exists  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
Darooma,

ну например строку из идентификаторов, или например xml - которые можно распарсить потом в таблицу, а можете воспользоватсья табличными параметрами, типа такого
use tempdb;
go
create table CustomerStores (CustomerId int, StoreId int, primary key (CustomerId, StoreId))
insert into CustomerStores values (1,1),(1,2),(2,3),(2,4)
go
create type CustomerStoresInputParam as table (CustomerId int, StoreId int, act char(1), primary key (CustomerId,StoreId) )
go
create proc CustomerStores_merge @CustomerStores CustomerStoresInputParam readonly
as
merge into 
	CustomerStores cs
using 
	(select CustomerId, StoreId, act from @CustomerStores) i on 
	i.CustomerId = cs.CustomerId and i.StoreId = cs.StoreId
when 
	matched and i.act = 'D' then delete
when 
	not matched and i.act = 'I' then insert (CustomerID, StoreID) values (i.CustomerID, i.StoreID);
go

--- заполнение параметров и вызов
declare @CustomerStores CustomerStoresInputParam
insert into @CustomerStores
values (1,2,'D'),(1,5,'I'),(2,4,'D'),(2,5,'I'),(1,1,'I')

exec CustomerStores_merge @CustomerStores
select * from CustomerStores
go

drop table CustomerStores
drop proc CustomerStores_merge
drop type CustomerStoresInputParam
10 июн 11, 16:36    [10797941]     Ответить | Цитировать Сообщить модератору
 Re: @@ROWCOUNT и Exists  [new]
Darooma
Member

Откуда:
Сообщений: 758
благодарю
10 июн 11, 17:00    [10798143]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить