powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Апдейт записей в таблице с уникальным индексом
15 сообщений из 15, страница 1 из 1
Апдейт записей в таблице с уникальным индексом
    #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
Апдейт записей в таблице с уникальным индексом
    #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
Апдейт записей в таблице с уникальным индексом
    #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
Апдейт записей в таблице с уникальным индексом
    #39708559
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sergey TSA,

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

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

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

Проставить на одном любое значение (99999) потом менять оба.
в транзакции отключить констрейн менять включить констрейнНе 99999, а NULL. Тогда и констрейнт отключать не придётся.
Естественно, поля FLD1 и FLD2 должны допускать значение NULL.
ну такого(nullable) по условиям нет
...
Рейтинг: 0 / 0
Апдейт записей в таблице с уникальным индексом
    #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
Апдейт записей в таблице с уникальным индексом
    #39708611
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TaPaKПроставить на одном любое значение (99999) потом менять оба.Но наверняка нужно, что бы много пользователей могло выполнить эту процедуру.
Поэтому нужно сделать механизм хранения свободных резервных FLD для обмена. А логику реализовать в instead-off триггере :-)
Что делать, придётся извращаться, раз накладываются всякие ограничения, типа "На самом деле мы апдейтим по одной записи"
...
Рейтинг: 0 / 0
Апдейт записей в таблице с уникальным индексом
    #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
Апдейт записей в таблице с уникальным индексом
    #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
Апдейт записей в таблице с уникальным индексом
    #39708780
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sergey TSAНу можно и нулл, но все равно уникальность нарушится, если кто-то еще будет менять другие записи.
Фильтрованные индексы?
Не, не слыхал.
...
Рейтинг: 0 / 0
Апдейт записей в таблице с уникальным индексом
    #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
Апдейт записей в таблице с уникальным индексом
    #39708971
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PizzaPizzaНо я не могу придумать зачем бы мне такое было нужно
Ээээ, батенька, больное воображение иных "архитекторов" ишо не такие кундштюки может придумывать.
...
Рейтинг: 0 / 0
Апдейт записей в таблице с уникальным индексом
    #39709121
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
aleks222PizzaPizzaНо я не могу придумать зачем бы мне такое было нужно
Ээээ, батенька, больное воображение иных "архитекторов" ишо не такие кундштюки может придумывать.Например, уникальное поле сортировки (приоритета)
...
Рейтинг: 0 / 0
15 сообщений из 15, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Апдейт записей в таблице с уникальным индексом
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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