Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Апдейт записей в таблице с уникальным индексом / 15 сообщений из 15, страница 1 из 1
26.09.2018, 14:35
    #39708494
Sergey TSA
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Апдейт записей в таблице с уникальным индексом
Здравствуйте!
Возникла необходимость проапдейтить 2 записи в таблице, на которой есть уникальный индекс.
Причем при апдейте первой записи возникает нарушение этой уникальности и апдейт не проходит.
Это нарушение не возникало бы, если бы можно было проапдейтить и 1ю и 2ю запись, но до 2го апдейта дело не доходит.

Пример таблицы:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
create table TBL1 
	(PK int identity primary key,
	FLD1 int not null,
	FLD2 int not null,
	FLD3 int)
go
create unique index IDX1 on TBL1 (FLD1, FLD2)
go

insert into TBL1 (FLD1, FLD2, FLD3) values (1, 1, 1)
insert into TBL1 (FLD1, FLD2, FLD3) values (2, 1, 2)



В реальной таблице FK1 - это референс на другую таблицу
Хочется выполнить такие запросы:

Код: sql
1.
2.
3.
4.
5.
6.
7.
update TBL1 
	set FLD1 = 2
	where PK = 1

update TBL1 
	set FLD1 = 1
	where PK = 2



Естественно, 1й апдейт отваливается. Есть какие-нибудь рекомендации, как этого лучше всего добиться?
В голову приходят 2 варианта:
1. Вообще убрать уникальный индекс. Но тогда теряется контроль уникальности на уровне БД.
2. Сначала удалить обе записи, потом заинсертить. Тоже вариант не очень нравится - записей может быть и больше двух.
Есть еще какие-нибудь варианты?
...
Рейтинг: 0 / 0
26.09.2018, 14:42
    #39708497
court
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Апдейт записей в таблице с уникальным индексом
Код: sql
1.
2.
3.
update TBL1 
	set FLD1 = case when PK=1 then 2 when PK=2 then 1 end
	where PK in (1,2)


?
...
Рейтинг: 0 / 0
26.09.2018, 15:30
    #39708548
Sergey TSA
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Апдейт записей в таблице с уникальным индексом
court,

Спасибо, это конечно сработает, но хотелось бы тогда усложнить вопрос) На самом деле мы апдейтим по одной записи, через хранимку:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
create procedure UpdateTbl1
	@Fld1 int, 
	@PK int
as begin
	update TBL1
		set FLD1 = @Fld1
		where PK = @PK
end



Есть ощущение, что с таким подходом искомого результата не добиться, но вдруг все же есть решение
...
Рейтинг: 0 / 0
26.09.2018, 15:37
    #39708559
TaPaK
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Апдейт записей в таблице с уникальным индексом
Sergey TSA,

Проставить на одном любое значение (99999) потом менять оба.
в транзакции отключить констрейн менять включить констрейн
...
Рейтинг: 0 / 0
26.09.2018, 15:54
    #39708574
Владимир Затуливетер
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Апдейт записей в таблице с уникальным индексом
Включение констрейнта очень накладно, на больших таблицах однозначно не стоит так делать.

Вообще оптимальный вариант это просто создать новую процедуру которая вам сделает нужный апдейт, других приемлемых вариантов нет...
...
Рейтинг: 0 / 0
26.09.2018, 16:05
    #39708586
iap
iap
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Апдейт записей в таблице с уникальным индексом
TaPaKSergey TSA,

Проставить на одном любое значение (99999) потом менять оба.
в транзакции отключить констрейн менять включить констрейнНе 99999, а NULL. Тогда и констрейнт отключать не придётся.
Естественно, поля FLD1 и FLD2 должны допускать значение NULL.
...
Рейтинг: 0 / 0
26.09.2018, 16:17
    #39708597
TaPaK
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Апдейт записей в таблице с уникальным индексом
iapTaPaKSergey TSA,

Проставить на одном любое значение (99999) потом менять оба.
в транзакции отключить констрейн менять включить констрейнНе 99999, а NULL. Тогда и констрейнт отключать не придётся.
Естественно, поля FLD1 и FLD2 должны допускать значение NULL.
ну такого(nullable) по условиям нет
...
Рейтинг: 0 / 0
26.09.2018, 16:23
    #39708610
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Апдейт записей в таблице с уникальным индексом
Sergey TSAЕсть ощущение, что с таким подходом искомого результата не добиться, но вдруг все же есть решениеНапример, перепишите так:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
create procedure BatchUpdateTBL1
 @data xml
as
begin
 update t
  set
   FLD1 = s.FLD1
 from
  @d.nodes('/item') d(n) cross apply
  (select d.n.value('@PK', 'int'), d.n.value('@FLD1', 'int')) s(PK, FLD1) join
  TBL1 t on t.PK = s.PK
end;
go

create procedure UpdateTbl1
	@Fld1 int, 
	@PK int
as begin
 declare @data xml

 select @data = t.x from (select @PK as [@PK], @Fld1 as [@FLD1] for xml path('item'), type) t(x);

 exec BatchUpdateTBL1 @data;
end;
go


Тогда, не меняяя логику работы с UpdateTbl1, сможете сделать так:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
...
declare @data xml;

select
 @data = t.x
from
 (select PK as [@PK], Fld1 as [@FLD1] from (values (1, 2), (2, 1)) a(PK, Fld1) for xml path('item'), type) t(x);

exec BatchUpdateTBL1 @data;
...


Вместо xml можно применить табличный тип, при условии, что его определение не придется менять.
...
Рейтинг: 0 / 0
26.09.2018, 16:23
    #39708611
alexeyvg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Апдейт записей в таблице с уникальным индексом
TaPaKПроставить на одном любое значение (99999) потом менять оба.Но наверняка нужно, что бы много пользователей могло выполнить эту процедуру.
Поэтому нужно сделать механизм хранения свободных резервных FLD для обмена. А логику реализовать в instead-off триггере :-)
Что делать, придётся извращаться, раз накладываются всякие ограничения, типа "На самом деле мы апдейтим по одной записи"
...
Рейтинг: 0 / 0
26.09.2018, 17:04
    #39708657
Sergey TSA
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Апдейт записей в таблице с уникальным индексом
Всем спасибо!

TaPaKiapпропущено...
Не 99999, а NULL. Тогда и констрейнт отключать не придётся.
Естественно, поля FLD1 и FLD2 должны допускать значение NULL.
ну такого(nullable) по условиям нет

Ну можно и нулл, но все равно уникальность нарушится, если кто-то еще будет менять другие записи.
авторColumns that are used in a unique index should be set to NOT NULL, because multiple null values are considered duplicates when a unique index is created.

Владимир ЗатуливетерВключение констрейнта очень накладно, на больших таблицах однозначно не стоит так делать.

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

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

invm, спасибо, попробую.
...
Рейтинг: 0 / 0
26.09.2018, 17:05
    #39708659
TaPaK
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Апдейт записей в таблице с уникальным индексом
Sergey TSA,

авторColumns that are used in a unique index should be set to NOT NULL, because multiple null values are considered duplicates when a unique index is created.

не смогли перевести?
...
Рейтинг: 0 / 0
26.09.2018, 19:39
    #39708780
aleks222
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Апдейт записей в таблице с уникальным индексом
Sergey TSAНу можно и нулл, но все равно уникальность нарушится, если кто-то еще будет менять другие записи.
Фильтрованные индексы?
Не, не слыхал.
...
Рейтинг: 0 / 0
26.09.2018, 22:11
    #39708837
PizzaPizza
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Апдейт записей в таблице с уникальным индексом
Sergey TSAХочется выполнить такие запросы:

Код: sql
1.
2.
3.
4.
5.
6.
7.
update TBL1 
	set FLD1 = 2
	where PK = 1

update TBL1 
	set FLD1 = 1
	where PK = 2




А можно узнать, что за задача у вас. По сути вам нужно поменять местами два id при этом отдельными запросами (что без третьего id невозможно). Но я не могу придумать зачем бы мне такое было нужно на постоянной основе. Или это у вас разовая акция?
...
Рейтинг: 0 / 0
27.09.2018, 05:57
    #39708971
aleks222
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Апдейт записей в таблице с уникальным индексом
PizzaPizzaНо я не могу придумать зачем бы мне такое было нужно
Ээээ, батенька, больное воображение иных "архитекторов" ишо не такие кундштюки может придумывать.
...
Рейтинг: 0 / 0
27.09.2018, 11:01
    #39709121
alexeyvg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Апдейт записей в таблице с уникальным индексом
aleks222PizzaPizzaНо я не могу придумать зачем бы мне такое было нужно
Ээээ, батенька, больное воображение иных "архитекторов" ишо не такие кундштюки может придумывать.Например, уникальное поле сортировки (приоритета)
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Апдейт записей в таблице с уникальным индексом / 15 сообщений из 15, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]