需要帮助将此游标转换为基于集合的操作

RK *_*ala 0 sql-server t-sql

我有一个存储过程,它作为报告数据库每晚刷新的一部分运行,大约需要 2 个小时才能完成。该对象B_RPT_RC_AUDIT_ASSIGNED_TO_TEMP_T2有 800 万行。您能否建议我如何将此光标转换为基于集合的方法以获得更好的性能?可以使用 CTE 吗?

ALTER PROCEDURE [dbo].[B_RPT_RC_AUDIT_ASSIGNED_TO_TEMP2_SP] AS      
SET NOCOUNT ON        
DECLARE @SEQ SMALLINT,      
@CASEID DECIMAL,       
@ASSIGNED  NCHAR(30),      
@AUDITSTAMP DATETIME,      
@AUDITOPRID NCHAR(60),      
@STATUS NCHAR(10),      
@LASTCASEID DECIMAL,       
@PROVGRPID NCHAR(20)      
SET @SEQ = 1      
SET @LASTCASEID = @CASEID      

DROP TABLE B_RPT_RC_AUDIT_ASSIGNED_TO_TEMP   

CREATE TABLE B_RPT_RC_AUDIT_ASSIGNED_TO_TEMP (      
  SEQ_NUM SMALLINT,       
  CASE_ID DECIMAL,       
  ASSIGNED_TO NCHAR(30),       
  AUDIT_STAMP DATETIME,       
  AUDIT_OPRID NCHAR(60),      
  RC_STATUS NCHAR(10),      
  PROVIDER_GRP_ID NCHAR(20) )      
DECLARE AUDIT CURSOR FOR        
   SELECT CASE_ID, ASSIGNED_TO, AUDIT_STAMP, AUDIT_OPRID, RC_STATUS, PROVIDER_GRP_ID      
   FROM B_RPT_RC_AUDIT_ASSIGNED_TO_TEMP_T2      

-- Open the cursor      
OPEN AUDIT      
FETCH NEXT      
   FROM AUDIT      
    INTO @CASEID, @ASSIGNED, @AUDITSTAMP, @AUDITOPRID, @STATUS, @PROVGRPID       
WHILE @@FETCH_STATUS = 0      

begin       
 INSERT INTO B_RPT_RC_AUDIT_ASSIGNED_TO_TEMP       
 SELECT @SEQ, @CASEID, @ASSIGNED, @AUDITSTAMP, @AUDITOPRID, @STATUS, @PROVGRPID      

SET @LASTCASEID = @CASEID      
FETCH NEXT      
   FROM AUDIT      
    INTO @CASEID, @ASSIGNED, @AUDITSTAMP, @AUDITOPRID, @STATUS, @PROVGRPID      

SET @SEQ = CASE WHEN @CASEID <> @LASTCASEID THEN 1 WHEN @CASEID = @LASTCASEID THEN @SEQ + 1 END      
end      
-- Close and deallocate the cursor      
CLOSE AUDIT      
DEALLOCATE AUDIT
Run Code Online (Sandbox Code Playgroud)

孔夫子*_*孔夫子 6

为什么每次都需要 DROP 和 RECREATE 表?由于您正在执行 DROP-CREATE,因此它必须已经存在。因此,在 SP 之外,按如下方式重新创建它:

CREATE TABLE B_RPT_RC_AUDIT_ASSIGNED_TO_TEMP (      
  SEQ_NUM SMALLINT,       
  CASE_ID DECIMAL,       
  ASSIGNED_TO NCHAR(30),       
  AUDIT_STAMP DATETIME,       
  AUDIT_OPRID NCHAR(60),      
  RC_STATUS NCHAR(10),      
  PROVIDER_GRP_ID NCHAR(20),
  PRIMARY KEY(CASE_ID, SEQ_NUM)
); -- don't leave an 8 million record table in a heap!
Run Code Online (Sandbox Code Playgroud)

由于您所需要的只是将 CASE 中的记录编号从 1 到 N,因此您可以使用ROW_NUMBER()

ALTER PROCEDURE [dbo].[B_RPT_RC_AUDIT_ASSIGNED_TO_TEMP2_SP]
AS
  SET NOCOUNT ON;
  TRUNCATE TABLE B_RPT_RC_AUDIT_ASSIGNED_TO_TEMP;

  INSERT INTO B_RPT_RC_AUDIT_ASSIGNED_TO_TEMP       
  SELECT ROW_NUMBER() OVER (PARTITION BY CASE_ID ORDER BY AUDIT_STAMP),
         CASE_ID, ASSIGNED_TO, AUDIT_STAMP, AUDIT_OPRID, RC_STATUS, PROVIDER_GRP_ID      
    FROM B_RPT_RC_AUDIT_ASSIGNED_TO_TEMP_T2;
GO
Run Code Online (Sandbox Code Playgroud)