Tom*_*Tom 5 sql-server t-sql sql-server-2014
首先:这是用于序列化的 ETL 存储过程,因此并行性无关紧要。
我需要在加载期间为标记分配自定义 ID 号。我不能使用身份字段,因为 ID 号是唯一的“桶号” - 本质上是另一个编号字段。
我目前使用以下代码:
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
Run Code Online (Sandbox Code Playgroud)
我不喜欢它。它使用我更喜欢避免的游标。(旁注:此代码未经测试)
有没有办法在没有光标的情况下更有效地做到这一点?添加新元素时,IR 编号必须从使用的最高值开始增加。存在多个存储桶(按存储桶编号)并具有自己的编号。
我总是一次只处理一个桶的数据(一个桶在 sim 中,一个在 simstg 中)。
使用单个语句和ROW_NUMBER(). 使用适当的索引,它可能比游标更有效。
请注意,我将 thep.[BucketRef] = @stgBucketNo从 theWHERE移到了ON子句。你拥有它的方式,使LEFT JOIN工作成为一个INNER JOIN.
WITH
starting (Id) AS
( SELECT ISNULL( ( SELECT TOP (1) v.Id
FROM sim.[Variable] AS v
WHERE v.BucketRef = @simBucketNo
ORDER BY v.Id DESC
), 0)
),
variables AS
( SELECT
p.[Variable],
idRunner = s.Id + ROW_NUMBER() OVER (ORDER BY p.[Variable])
FROM starting AS s
CROSS JOIN simstg.[Parameter] AS p
LEFT OUTER JOIN sim.[Variable] AS v
ON p.[Variable] = v.[Code]
AND p.BucketRef = @stgBucketNo
WHERE v.BucketRef = @simBucketNo
AND v.Code IS NULL
GROUP BY p.[Variable]
)
INSERT INTO sim.[Variable]
([BucketRef], [VariableNo], [Code])
SELECT @simBucketNo, v.idRunner, v.[Variable]
FROM variables AS v ;
Run Code Online (Sandbox Code Playgroud)
公共表子查询 ( WITH) 只是为了清楚起见 - 并且类似于原始代码。您可以轻松地在没有它们的情况下重写语句:
INSERT INTO sim.[Variable]
([BucketRef], [VariableNo], [Code])
SELECT
@simBucketNo,
idRunner = ISNULL( ( SELECT TOP (1) v.Id
FROM sim.[Variable] AS v
WHERE v.BucketRef = @simBucketNo
ORDER BY v.Id DESC
), 0)
+ ROW_NUMBER() OVER (ORDER BY p.[Variable])
p.[Variable],
FROM simstg.[Parameter] AS p
LEFT OUTER JOIN sim.[Variable] AS v
ON p.[Variable] = v.[Code]
AND p.BucketRef = @stgBucketNo
WHERE v.BucketRef = @simBucketNo
AND v.Code IS NULL
GROUP BY p.[Variable] ;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
615 次 |
| 最近记录: |