Hola, chicos,
¡Buen día!
Hoy les mostraré cómo actualizar o eliminar una cantidad fija de registros de una tabla, que se puede usar para manipular los datos de la tabla sin bloquearla durante mucho tiempo durante la ejecución de la consulta.
Generación de una base simple.
Demostraré cómo crear la base de prueba que usaremos en esta publicación.
IF (OBJECT_ID('tempdb..#Teste') IS NOT NULL) DROP TABLE #Teste
CREATE TABLE #Teste (
Linha INT IDENTITY(1, 1),
Valor FLOAT,
Processado BIT DEFAULT 0
)
INSERT INTO #Teste(Valor)
SELECT 125.99
INSERT INTO #Teste(Valor)
SELECT 457.64
INSERT INTO #Teste(Valor)
SELECT 124.77
INSERT INTO #Teste(Valor)
SELECT 3687.48
INSERT INTO #Teste(Valor)
SELECT 14.47
INSERT INTO #Teste(Valor)
SELECT 758.51
INSERT INTO #Teste(Valor)
SELECT 288.05
ACTUALIZAR ARRIBA
Mucha gente no lo sabe, pero la declaración UPDATE admite el uso de TOP para delimitar la cantidad de registros que se actualizarán:
UPDATE TOP (1) #Teste
SET Processado = 1

Aunque es muy sencillo, este comando puede acabar engañándote. Esto sucede porque cuando usas un comando SUPERIOR sin usar ORDER BY, el resultado no es determinista. Cada vez que uses un TOP, debes usar un ORDER BY para indicarle a la base de datos cómo ordenarás los resultados y luego filtrar usando el TOP. Incluso si la tabla tiene un índice agrupado, esto no garantiza que los datos se ordenarán utilizando el índice agrupado o con el RowID en el caso de tablas HEAP.
Aunque ACTUALIZAR admite TOP, no admite ORDER BY. Para solucionar esta situación, podemos realizar la misma actualización de esta forma:
UPDATE A
SET Processado = 1
FROM #Teste A
JOIN (
SELECT TOP 2 *
FROM #Teste WITH(NOLOCK)
ORDER BY Linha DESC
) B ON B.Linha = A.Linha
O se puede hacer con CTE (Common Table Expressions), que es una forma más elegante y eficiente:
;WITH CTE AS
(
SELECT TOP 2 *
FROM #Teste WITH(NOLOCK)
ORDER BY Linha DESC
)
UPDATE CTE
SET Processado = 1
Resultado:

Comparando el plan de ejecución:


Como se indicó anteriormente, la solución que utiliza CTE es más elegante y eficaz, se ejecuta en menos tiempo y consume menos disco y CPU.
BORRAR ARRIBA
Así como usamos en ACTUALIZAR, podemos usar TOP en el propio DELETE, corriendo el riesgo de eliminar registros aleatorios y también podemos usar ORDER BY, tanto JOIN en actualización como CTE para filtrar y limitar los registros que serán eliminados:
-- Apagando o primeiro registro (não há garantias de ser o primeiro registro)
DELETE TOP(1)
FROM #Teste A
-- Apagando o último registro utilizando JOIN
DELETE A FROM #Teste A
JOIN (
SELECT TOP 1 *
FROM #Teste WITH(NOLOCK)
ORDER BY Linha DESC
) B ON B.Linha = A.Linha
-- Apagando o último registro utilizando CTE
;WITH CTE AS
(
SELECT TOP 1 *
FROM #Teste WITH(NOLOCK)
ORDER BY Linha DESC
)
DELETE CTE
Ejemplo:

¡Eso es todo, amigos!
Un abrazo y nos vemos en el próximo post.
Comentários (0)
Carregando comentários…