2016-12-01 9 views
0

200M以上のレコードをロードするはずの動的SQLクエリを実行しようとしています。私は一度にすべてのレコードを読み込もうとしましたが、System.OutOfMemory例外を取得しました。したがって、時間間隔を月単位で区切ることにしました.1ヶ月間実行しても、1時間以上実行されます。私は日付をハードコードし、 'While'なしでそれを実行し、正常に動作します。誰かがそれに何らかのエラーがあるかどうかをチェックして知らせることができますか?以下 は、それはあなたが道複数の変数/日を持っているように、あなたが必要とするよりも、見て、あなたがリンクサーバー名またはいくつかの他を渡したいと思っていない限り、あなたは、動的SQLを必要としないというのが私のクエリ動的SQLの実行が長すぎます

DECLARE @FromDate VARCHAR(MAX)='', 
     @params nvarchar(max) = N'@StartDate Date out,@EndDate Date out,@FromDate date out,@ToDate date out', 
     @SQL NVARCHAR(MAX)=’’, 
     @ToDate VARCHAR(MAX)='', 
     @StartDate VARCHAR(MAX)=’’, 
     @EndDate VARCHAR(MAX)=’’; 

SELECT @FromDate= DATEADD(DAY,-365, GETUTCDATE()), @ToDate =  GETUTCDATE(); 
SELECT @[email protected], @EndDate=CAST(DATEADD(MONTH,1, @FromDate) AS DATE); 
SET @SQL = ' 
WHILE ''' + @FromDate + ''' < ''' + @ToDate + ''' 
    BEGIN 
    INSERT INTO dbo.Sales 
    (
    ProductID, 
    SaleDate, 
    Quantity 
    ) 
Select 
     ProductID, 
     SaleDate, 
     Quantity 
from 
    OPENQUERY(TeraData1,'' 
     Select 
     PR_ID   AS ProductID, 
     SL_Date   AS SaleDate, 
     PR_QTY   AS Quantity 
    FROM 
     Sales.Product 
    where 
SaleDate BETWEEN ' + @StartDate + 'AND '+ @EndDate + ' 
'') 

SET @FromDate =DATEADD(MONTH,1,'''+ @FromDate +''') 
SET @StartDate =DATEADD(MONTH,1,'''+ @StartDate +''') 
SET @EndDate =DATEADD(MONTH,1,'''+ @EndDate +''') 
END’ 

EXECUTE sp_executesql @SQL, @params, 
       @[email protected], 
       @[email protected], 
       @StartDate = @StartDate out, 
       @EndDate = @EndDate out; 
+1

代わりに、動的SQLのストアドプロシージャ/ファンクション・ロジックを使用しないのはなぜ? –

+1

@ TonyDongには、動的SQLを必要とする構文を使用している文法に何もない点があります。通常のWHILE制御構文を使用できます。そして、少し難しいですが、どういう問題ですか?ダイナミックSQLとコントロールフローの間で変数の範囲を混在させているということです。 – Matt

+1

また、問題の一部となるデータ型も混在しています – Matt

答えて

2
DECLARE @FromDate DATE 

SET @FromDate = DATEADD(YEAR,-1,GETUTCDATE()) 

WHILE @FromDate < GETUTCDATE() 
BEGIN 
    INSERT INTO dbo.Sales 
    (
     ProductID, 
     SaleDate, 
     Quantity 
    ) 
Select 
     ProductID, 
     SaleDate, 
     Quantity 
from 
    OPENQUERY(TeraData1, 
     Select 
      PR_ID   AS ProductID, 
      SL_Date   AS SaleDate, 
      PR_QTY   AS Quantity 
     FROM 
      Sales.Product 
     where 
      SaleDate >= @FromDate AND SaleDate < DATEADD(MONTH,1,@FromDate) 
    ) 

    SET @FromDate =DATEADD(MONTH,1,@FromDate) 
END 

です列を動的に変更します。

SQLに必要な値を推測させる代わりに、パラメータに適切なデータ型を使用してください。

また、日付のBETWEENを使用すると、比較の制限1側を修正するために、包括的であるため特定の日付が重複していました。

あなたは、これが動的に非動的SQLにおける制御フローを維持し、ここにパラメータを渡す行いたいならば次に例を示します。

DECLARE @FromDate DATE 

SET @FromDate = DATEADD(YEAR,-1,GETUTCDATE()) 

WHILE @FromDate < GETUTCDATE() 
BEGIN 

    DECLARE @LinkedServerName NVARCHAR(MAX) = 'TeraData1' 
    DECLARE @ParamDef NVARCHAR(MAX) = '@FromDate DATE' 
    DECLARE @SQL NVARCHAR(MAX) 

    SET @SQL = ' 
     INSERT INTO dbo.Sales 
     (
     ProductID, 
     SaleDate, 
     Quantity 
    ) 
    Select 
     ProductID, 
     SaleDate, 
     Quantity 
    from 
     OPENQUERY(' + @LinkedServerName + ', 
      Select 
      PR_ID   AS ProductID, 
      SL_Date   AS SaleDate, 
      PR_QTY   AS Quantity 
      FROM 
      Sales.Product 
      where 
      SaleDate >= @FromDate AND SaleDate < DATEADD(MONTH,1,@FromDate) 
     )' 

    EXECUTE sp_executesql @SQL, @PramDef, @FromDate = @FromDate 

    SET @FromDate =DATEADD(MONTH,1,@FromDate) 
END 
関連する問題