BEGIN TRANSACTION
update person set Address1 = Address2, Address2 = null
where Address1 is null and Address2 is not null;
update person set Address2 = Address3, Address3 = null
where Address2 is null and Address3 is not null;
update person set Address1 = Address2, Address2 = null
where Address1 is null and Address2 is not null;
select top 100 * from person
ROLLBACK TRANSACTION
Это было бы очень уродливо, если бы у вас было много полей адреса, но для 3 это приемлемо.Не забудьте протестировать любую копию сценария и вставить ее из промежуточных сетей в транзакцию, которую вы откатываете, чтобы не стереть вашу базу данных:)
РЕДАКТИРОВАТЬ: с дополнительной информацией (6 полей адреса): вы можете сделать как вышетолько повторить 5 раз, чтобы переместиться, так что в худшем случае вы, где еще сделали
Declare StoredProcedure OneRound
BEGIN
update person set Address1 = Address2, Address2 = null
where Address1 is null and Address2 is not null;
update person set Address2 = Address3, Address3 = null
where Address2 is null and Address3 is not null;
update person set Address3 = Address4, Address4 = null
where Address3 is null and Address4 is not null;
update person set Address4 = Address5, Address5 = null
where Address4 is null and Address5 is not null;
update person set Address5 = Address6, Address6 = null
where Address5 is null and Address6 is not null;
END
Declare StoredProc FixAllAddresses
BEGIN
call OneRound
call OneRound
call OneRound
call OneRound
call OneRound
END
Вы также можете использовать cusor (предупреждающий псидо-код). Я не посмотрел синтаксис для курсоров T-SQL, и это былоНекоторое время, чтобы я неправильно понял детали, проверьте синтаксис в онлайн-справке.
Declare cursor @personCursor for select ID,Address1,Address2,... from person;
OPEN @personCursor
FETCH @personCursor into (@personID, @addr1, @addr2, @addr3...)
while(@@FETCH_STATUS)
BEGIN
IF @addr1 is null
BEGIN
IF @addr2 is not null
BEGIN
@addr1 = @addr2
@addr2 = null
END
ELSE IF @addr3 is not null
@addr1 = @addr3
@addr3 = null
BEGIN
-- Boaring, ugly code goes here for addr4,addr5,addr6
END
END
IF @addr2 is null
IF @addr3 is not null
BEGIN
@addr2 = @addr3
@addr3 = null
END
ELSE IF @addr4 is not null
@addr2 = @addr4
@addr4 = null
BEGIN
-- Boaring, ugly code goes here for addr5, addr6
END
BEGIN
-- repeat for addr3, addr4,
if @addr5 is null
BEGIN
IF addr6 is not null
BEGIN
@addr5 = @addr6
@addr6 = null
END
END
END
update person set address1 = @addr1, address2 = @addr2, ...
where PersonId = @personId
FETCH @personCursor into (@personID, @addr1, @addr2, @addr3...)
END
Начало хранимого процесса, вызываемое 5 раз, приводит к меньшему количеству кода и может быть менее подвержено ошибкам, курсор только перебирает ваших сотрудников один раз, но не фильтрует.Я подозреваю, что хранимое решение процесса ниже будет быстрее, но это будет зависеть от ваших данных.