2012-08-07 56 views
2

是否可以將以下光標寫入CTE?目前運行需要很長時間。將光標改爲CTE

這裏是我的代碼:

if @ReportSource = 'TAB' 

    BEGIN 
    DECLARE yr_cursor CURSOR 
    FOR 
     SELECT YEAR, RouteNum, RampInfo, BeginMeasure, EndMeasure, OriginalRoute, Description, CountyDesc, Incidents from #RptParms 

    OPEN yr_cursor; 



FETCH NEXT FROM yr_cursor INTO @Year, @RouteNum, @RampInfo, @BeginMeasure, @EndMeasure, @OriginalRoute, @Description, @CountyDesc, @Incidents; 


WHILE (@@FETCH_STATUS = 0) 

    BEGIN 

     SELECT @sql_str_fred = N'SELECT route_number, beg_measure AS MILELOG, AADT_TOTAL AS VMT, end_measure, RCLINK,YEAR 
           FROM VW_FRED_AADT_HIST 
           WHERE route_number = '''+ @RouteNum + ''' 
           and YEAR = '''+ @Year + ''' 
           and FIPS_AND_COUNTY Like ' + '''%' + @CountyDesc + ''' 
           and beg_measure BETWEEN '+ cast(@BeginMeasure as varchar(8)) + ' and ' + cast(@EndMeasure as varchar(8)) + '' 




     SELECT @sql_str_fred = N' SELECT * from OPENQUERY(EDWGEARS, ''' + REPLACE(@sql_str_fred, '''', '''''') + ''')' 


         INSERT #freddata (ROUTE_NBR , 
             MILELOG , 
             VMT , 
             END_MEASURE , 
             RCLINK , 
             YEAR)   
         EXEC sp_ExecuteSQL @sql_str_fred 




       FETCH NEXT FROM yr_cursor INTO @Year, @RouteNum, @RampInfo, @BeginMeasure, @EndMeasure, @OriginalRoute, @Description, @CountyDesc, @Incidents; 

      END 

    CLOSE yr_cursor 
    DEALLOCATE yr_cursor 

END; 
+4

事實上,你正在做一個鏈接服務器的SP在每次迭代執行表明,這是不會用CTE的原樣工作;也許有一種方法可以在一次打擊中將所有相關數據傳遞給鏈接服務器,否則我會猜測你將不得不循環。 – AakashM 2012-08-07 15:42:49

+0

哪位? CTE應該比光標快的原因沒有什麼原因。 – 2012-08-07 15:44:34

+0

通過循環需要多少時間?你有多少個循環(平均)?您能否首先將遠程數據的一個子集複製到本地臨時表中? – milivojeviCH 2012-12-28 08:48:12

回答

0

假設#RptParms - 是pameter值的表,而不是巨大的... 然後,所有參數可與查詢相結合這樣的:

-- The maximum length of the query string in OPENQUERY is 8 KB !!! 
declare 
    @sql varchar(max) = ' 
;WITH lst AS (
    SELECT * FROM (VALUES 
--- values --- 
    ) aa(rn,yr,dsc,m1,m2) 
) SELECT route_number, beg_measure AS MILELOG, AADT_TOTAL AS VMT, end_measure, RCLINK,YEAR 
FROM VW_FRED_AADT_HIST lst 
WHERE route_number = lst.rn 
    and YEAR = lst.yr 
    and FIPS_AND_COUNTY Like lst.dsc 
    and beg_measure BETWEEN lst.m1 and lst.m2 
' 

    select @sql = REPLACE(@sql, '--- values ---', '--- values ---, 
(' + ISNULL('''' + RouteNum       + '''', 'NULL')  -- rn:  1234 --> '1234' or --> NULL 
+ ',' + ISNULL('''' + YEAR        + '''', 'NULL')  -- yn:  1234 --> '1234' 
+ ',' + ISNULL('''%' 
     + replace(replace(replace(replace(Description 
      , '[', '[[]') 
      , '%', '[%]') 
      , '_', '[_]') 
      , '''', '''''') 
     + '''', 'NULL')              -- dsc: a_b[c]%d'e --> '%a[_]b[[]c][%]d''e' 
+ ',' + ISNULL('''' + cast(BeginMeasure as varchar(8)) + '''', 'NULL')  -- m1:  1234 --> '1234' 
+ ',' + ISNULL('''' + cast(EndMeasure as varchar(8)) + '''', 'NULL')  -- m2:  1234 --> '1234' 
+ ')') 
    from #RptParms 

-- print @sql 
/* 
;WITH lst AS (
    SELECT * FROM (VALUES 

--- values ---, 
('1234','1234','%a[_]b[[]c][%]d''e','1234','1234'), 
('222',NULL,'%abcde','1234','1234'), 
(NULL,'1234','%a[_]b[[]c][%]d''e','1234','1234') 

    ) aa(rn,yr,dsc,m1,m2) 
) SELECT route_number, beg_measure AS MILELOG, AADT_TOTAL AS VMT, end_measure, RCLINK,YEAR 
FROM VW_FRED_AADT_HIST, lst 
WHERE route_number = lst.rn 
    and YEAR = lst.yr 
    and FIPS_AND_COUNTY Like lst.dsc 
    and beg_measure BETWEEN lst.m1 and lst.m2 
*/ 

INSERT #freddata (ROUTE_NBR, MILELOG, VMT, END_MEASURE, RCLINK, YEAR) 
    SELECT * 
    from OPENQUERY(EDWGEARS, @sql) 

再一次: OPENQUERY中查詢字符串的最大長度是8 KB !!!