Estou implementando uma fila como um buffer de anel em uma tabela ao longo das linhas do que Thomas Kejser fala aqui: Implementando filas de mensagens em bancos de dados relacionais Se o buffer de anel ficar cheio, tenho que aumentar o número de slots e possivelmente mudar alguns deles os valores ao redor. Isso faz parte da minha rotina para adicionar slots ao buffer de anel
Eu tenho uma tabela que se parece com isso:
SlotId SlotVal1 SlotVal2
1 3 3
2 4 4
3 1 1
4 2 2
5 NULL NULL
6 NULL NULL
7 NULL NULL
8 NULL NULL
Eu gostaria de "deslocar" os valores dos slots 3 e 4 para frente em 4 slots para as linhas 7 e 8 para que a tabela ficasse assim:
SlotId SlotVal1 SlotVal2
1 3 3
2 4 4
3 NULL NULL
4 NULL NULL
5 NULL NULL
6 NULL NULL
7 1 1
8 2 2
Tentei duas consultas UPDATE diferentes para deslocar as linhas para frente e, em seguida, limpar as linhas anteriores. A primeira consulta (conforme reproduzida abaixo) não atualiza nenhuma linha da minha tabela e estou deixando em branco o que devo ter deixado de fora:
-- shift slot values forward
DECLARE @firtRowToMove AS int = 3; -- slot id of the first row to move
DECLARE @rowsToShift AS int = 4; -- number of rows forward to shift
UPDATE [SlotTable]
SET [SlotVal1] = (SELECT [SlotVal1]
FROM [SlotTable] AS s2
WHERE s2.[SlotId] = ([SlotId] - @rowsToShift)),
[SlotVal2] = (SELECT [SlotVal2]
FROM [SlotTable] AS s2
WHERE s2.[SlotId] = ([SlotId] - @rowsToShift))
WHERE [SlotId] >= (@firtRowToMove + @rowsToShift);
Você precisa se qualificar
SlotId
em sua subconsulta comSlotTable
ou usará oSlotId
da própria subconsulta.SQL Fiddle
BTW, sua versão CTE também não funciona
Outra maneira de fazer o que você faz nesta instrução de atualização é um pouco mais eficiente (pelo menos em meus testes).
Consegui uma versão da consulta com um CTE para funcionar para mim, mas, como Mikael Eriksson aponta em sua resposta, não tinha nada a ver com o uso de um CTE e tudo a ver com qualificar totalmente a referência ambígua à coluna SlotId no sub-selecionar.