如果遇到性能问题,在SQL中使用游标的最佳替代方法是什么?
我得到了以下代码,其中它使用Cursor循环并插入记录。
DECLARE @AuditBatchID_logRow INT,
@AuditOperationID_logRow INT,
@RowIdentifier_logRow nvarchar(200),
@AuditDBTableID_logRow INT,
@AuditLogRowID INT,
@AuditDBColumnID INT,
@NewValue nvarchar(200),
@PreviousVaue nvarchar(200),
@NewDisplayValue nvarchar(200)
DECLARE Crsr_AUDITLOGROW CURSOR LOCAL FORWARD_ONLY STATIC
FOR
SELECT [t0].[AuditBatchID],
[t1].[AuditOperationID],
[t1].[RowIdentifier],
[t0].[AuditTableID],
[t1].[AuditLogRowID]
FROM [AuditBatchTable] AS [t0]
INNER JOIN [AuditLogRow] AS [t1]
ON [t0].[AuditBatchTableID] = [t1].[AuditBatchTableID]
Open Crsr_AUDITLOGROW
FETCH NEXT FROM Crsr_AUDITLOGROW
INTO @AuditBatchID_logRow,
@AuditOperationID_logRow,
@RowIdentifier_logRow,
@AuditDBTableID_logRow,
@AuditLogRowID
While(@@FETCH_STATUS = 0)
BEGIN
INSERT INTO AuditLog(AuditLogRowID, AuditColumnID,
NewValue, OldDisplayValue, NewDisplayValue)
(SELECT @AuditLogRowID,
[ac].[AuditColumnID],
[t0].[UserEnteredValue],
[t0].[PreviousDisplayValue],
[t0].[DisplayValue]
FROM FMG_PROD.dbo.AuditLog AS [t0]
INNER JOIN FMG_PROD.dbo.AuditDBColumn AS [t1]
ON [t0].[AuditDBColumnID] = [t1].[AuditDBColumnID]
INNER JOIN FMG_PROD.dbo.AuditDBTable AS [t2]
ON [t1].[AuditDBTableID] = [t2].[AuditDBTableID]
INNER JOIN AuditTable AS [AT]
ON [t2].AuditDBTable = [AT].AuditTable
INNER JOIN AuditColumn AS [AC]
ON [AT].AuditTableID = [AC].AuditTableID
WHERE
([t0].[AuditBatchID] = @AuditBatchID_logRow)
AND ([t0].[AuditOperationID] = @AuditOperationID_logRow)
AND ([AT].[AuditTableID] = @AuditDBTableID_logRow)
AND [AC].AuditColumn = [t1].AuditDBColumn
AND (@RowIdentifier_logRow =
CASE ISNUMERIC(@RowIdentifier_logRow)
WHEN 1 then
CAST ([t0].[RowID] AS VARCHAR(200))
ELSE
CAST([t0].[RowGUID] AS VARCHAR(200))
END))
FETCH NEXT FROM Crsr_AUDITLOGROW
INTO @AuditBatchID_logRow,
@AuditOperationID_logRow,
@RowIdentifier_logRow,
@AuditDBTableID_logRow,
@AuditLogRowID
END
CLOSE Crsr_AUDITLOGROW
DEALLOCATE Crsr_AUDITLOGROW
答案 0 :(得分:8)
嗯,你正在思考和编写类似于结构化程序员的代码 - 一个接一个地线性地编程,对程序流程进行最严格的控制。这就是我们(几乎)所有人都被认为是编程的方式。
你需要像SQL人一样思考 - 在 SETS 数据中(不是单行,一次一个)。
避免需要严格控制算法的每一步 - 相反,只需告诉SQL Server WHAT - 不要 HOW 执行每一步!
最后,您将一堆行插入AuditLog
表中。为什么你需要一个游标?
INSERT INTO AuditLog(...list of columns.....)
SELECT (....list of columns....)
FROM Table1
INNER JOIN ..........
INNER JOIN .........
WHERE ........
你已经完成了!定义要插入表格中的 - 不要告诉SQL Server如何做到这一点令人厌烦 - 它会非常清楚,谢谢!
马克