Como início: isso é para um procedimento armazenado ETL que é serializado, portanto, o paralelismo não é motivo de preocupação.
Preciso atribuir números de ID personalizados para marcadores durante os carregamentos. Não posso usar um campo de identidade, porque os números de identificação devem ser exclusivos por um "número de balde" - essencialmente outro campo numerado.
Atualmente utilizo o seguinte código:
DECLARE @idRunner smallint
SELECT @idRunner = ISNULL(MAX([Id]),0)
FROM sim.[Variable]
WHERE [BucketRef] = @simBucketNo
DECLARE variable_cursor CURSOR FOR
SELECT DISTINCT p.[Variable]
FROM simstg.[Parameter] p
LEFT OUTER JOIN sim.[Variable] v ON (p.[Variable] = v.[Code])
WHERE p.[BucketRef] = @stgBucketNo
AND v.BucketRef = @simBucketNo
AND v.Code IS NULL
OPEN variable_cursor
DECLARE @variable VARCHAR(64)
FETCH NEXT FROM variable_cursor INTO @variable
WHILE @@FETCH_STATUS = 0
BEGIN
SET @idRunner = @idRunner + 1
INSERT INTO sim.[Variable] ([BucketRef], [VariableNo], [Code])
VALUES (@simBucketNo, @idRunner, @variable)
FETCH NEXT FROM variable_cursor INTO @variable
END
CLOSE variable_cursor
DEALLOCATE variable_cursor
e eu não gosto disso. Ele usa cursores que prefiro evitar. (Nota: este código não foi testado)
Existe uma maneira de fazer isso de forma mais eficiente, sem um cursor? Os números IR devem aumentar do mais alto usado quando novos elementos são adicionados. Existem vários baldes (por número de balde) e têm sua própria numeração.
Sempre irei processar dados para um balde por vez (um balde no sim, um no simstg).
Usando uma única instrução e
ROW_NUMBER()
. Com índices adequados, provavelmente será mais eficiente que cursores.Observe que movi o
p.[BucketRef] = @stgBucketNo
from theWHERE
para aON
cláusula. Do jeito que você tinha, fez oLEFT JOIN
trabalho como um arquivoINNER JOIN
.As subconsultas de tabela comuns (
WITH
) existem apenas para maior clareza - e para se assemelhar ao código original. Você pode facilmente reescrever a declaração sem eles:Você pode usar uma coluna de identidade em uma tabela temporária para evitar um cursor. Isso é especialmente conveniente com versões mais antigas do SQL Server que não oferecem suporte a
WITH
funções de janela.