2016-12-19 2 views
0

SQL Server 2008ジョブを15分ごとに実行してストアドプロシージャを呼び出します。これは問題なく動作しますが、最近、それは一日を通してランダムな時間に失敗し、そのストアドプロシージャを呼び出しているレポートで問題を引き起こしてきた。"## tmp_tbl"という名前のオブジェクトが既にデータベースに存在するため、SQL Serverジョブの実行に10-20%の時間がかかりません

Job history for this morning

元のクエリは、常にドロップするためのチェックが含まれていますテーブルが存在する場合

IF (SELECT OBJECT_ID('tempdb..##tmp_tbl')) IS NOT NULL 
    DROP TABLE ##tmp_tbl 

私もクエリをテストするために、同じパラメータで新しいプロシージャを作成し、私はここで見てきた他の質問に基づいて、それを変更しようとした:

IF SELECT OBJECT_ID('tempdb..##tmp_tbl') IS NOT NULL 
BEGIN 
    DROP TABLE ##tmp_tbl 
END 

かのチェックのすべてを変更することによって:

IF (SELECT OBJECT_ID('tempdb..##tmp_tbl')) IS NOT NULL 
    DROP TABLE ##tmp_tbl 

しかし、これはすべて、私が作成した新しいテストジョブを殺すことになりました。これは現在、平均45分間実行され、ほとんど毎回失敗します(おそらく私は間違っていましたか?

ほとんどの場合、ほとんどの時間稼働しているのに##tmp_tblの10-20%の時間が失敗する理由は誰にも分かりますか?

以下の全コード:

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 

ALTER PROCEDURE [dbo].[sp_GetGoaling_Outs] 
    @site varchar(4) 
AS 
BEGIN 
    SET NOCOUNT ON; 

    DECLARE @sqlStr nvarchar(max) 
    DECLARE @sqlStr2 nvarchar(max) 
    DECLARE @openQueryStr nvarchar(max) 
    DECLARE @so nvarchar(15) 
    DECLARE @goalDate nvarchar(10) 
    DECLARE @wc nvarchar(35) 
    DECLARE @wc2 nvarchar(35) 
    DECLARE @goal_yield smallint 
    DECLARE @early_goal_date nvarchar(10) 
    DECLARE @early_goal_yield smallint 

    --Declare @site varchar(4) 
    --set @site = 'OR01' 
    --[sp_GetGoaling_Outs] 'OR01' 

     --set @so = '147300' 
     --set @goalDate = '2016/02/24' 



IF (SELECT OBJECT_ID('tempdb..##tmp_tbl')) IS NOT NULL 
DROP TABLE ##tmp_tbl 


IF EXISTS (SELECT TOP 1 * FROM GoalTemp) --If the Goal Temp Table is empty, then do not run 
BEGIN 

    TRUNCATE TABLE Goal 
    INSERT INTO GOAL (shop_order,work_center, goal_yield, goal_date, early_goal_yield, early_goal_date) 
     SELECT shop_order,work_center, goal_yield, goal_date, early_goal_yield, early_goal_date 
     FROM GOALTemp 



    DECLARE db_cursor CURSOR FOR 
    SELECT shop_order, work_center, goal_date, goal_yield, early_goal_yield, early_goal_date 
    FROM Goal 
    --WHERE goal_date > DATEADD(mm,-2,GETDATE()) 

    OPEN db_cursor 
    FETCH NEXT FROM db_cursor INTO @so, @wc, @goalDate, @goal_yield, @early_goal_yield, @early_goal_date 

    WHILE @@FETCH_STATUS = 0 
    BEGIN 

    SET @wc2 = 'BDL_' + @wc 
    ----------------------------------------GET Yield (Outs) for work center to current date AND to end goal date-------------------------------------- 

    set @sqlStr = 'SELECT site, shop_order, work_center, goal_date, wc_outs, 
      (SELECT WC_OUTS_TO_NEED_DATE 
    FROM (
    --count the outs for the work center/max reporting operation seq 
     SELECT DISTINCT 
      COUNT(*) OVER (PARTITION BY shop_order, work_center ORDER BY shop_order) WC_OUTS_TO_NEED_DATE 
     FROM (
       SELECT * 
       FROM (
        --get the work center, reporting operation seq, and max reporting op seq for the route 
        SELECT base.site, base.shop_order,base.sfc, base.router, base.router_revision, 
      base.completeDateTime ,base.operation, base.work_center, cf.value rep_op_seq 
      , row_number() over (partition by base.shop_order, base.sfc, base.router, base.router_revision, base.operation, base.work_center order by base.shop_order) rownumber         
      , MAX(cf.value) OVER (PARTITION BY base.work_center) AS max_wc_op_rpt_seq 
      , MAX(cf.value) OVER (PARTITION BY base.work_center)+1 AS max_wc_op_rpt_seqPlus 
      FROM (
        --get only completes during the filtered time for the active shop orders 
        SELECT DISTINCT al.site, al.router, al.router_revision, al.sfc, 
        al.activity, al.reporting_center_bo 
        ,substr(al.shop_order_bo,instr(al.shop_order_bo, '','') + 1,length(al.shop_order_bo) - instr(al.shop_order_bo, '','')) shop_order 
        ,(al.date_time + to_number(concat(substr(extract(TIMEZONE_OFFSET from systimestamp), 1, 1), substr(extract(TIMEZONE_OFFSET from systimestamp), 12, 2)))/24) completeDateTime 
        , substr(o.reporting_center_bo,instr(o.reporting_center_bo, '','') + 1,length(o.reporting_center_bo)) work_center 
        , o.handle oHandle 
        , o.operation 
        FROM 
        wip.activity_log al, 
        wip.operation o 
        WHERE 
        al.action_code = ''COMPLETE'' 
        AND al.operation = o.operation 
        AND al.site = ''' + @site + ''' 

        AND trunc(al.date_time + to_number(concat(substr(extract(TIMEZONE_OFFSET from systimestamp), 1, 1), substr(extract(TIMEZONE_OFFSET from systimestamp), 12, 2)))/24) 
         <= TO_DATE(''' + @goalDate + ''',''yyyy/mm/dd'') 

        AND substr(al.shop_order_bo,instr(al.shop_order_bo, '','') + 1,length(al.shop_order_bo) - instr(al.shop_order_bo, '','')) 
            = ''' + @so + ''' 
      ) base 
       ,wip.router r, wip.router_step rs, wip.router_operation ro 
       ,(SELECT SUBSTR(handle,instr(handle, '','') + 1,length(handle) - instr(handle, '','') - 2) operation, attribute, value 
        FROM wip.custom_fields 
        WHERE attribute = ''REPORT_OP_SEQUENCE'') cf 
       WHERE 
       base.router = r.router (+)  
       AND base.router_revision = r.revision (+)   
       AND r.handle = rs.router_bo (+) 
       AND rs.handle = ro.router_step_bo (+) 
       AND substr(ro.operation_bo,1,length(ro.operation_bo)-2) = substr(base.oHandle,1,length(base.oHandle)-2) 
       AND base.operation = cf.operation (+) 
       AND base.work_center = ''' + @wc2 + ''' 
      ) 
      WHERE rownumber = 1 
     ) 
     WHERE rep_op_seq = max_wc_op_rpt_seq 
    )) WC_OUTS_TO_NEED_DATE ' 

    SET @sqlStr2 = ' FROM (
     SELECT DISTINCT site, shop_order 
     , work_center, ''' + @goalDate + ''' as goal_date, 
      COUNT(*) OVER (PARTITION BY shop_order, work_center ORDER BY shop_order) WC_OUTS 
     FROM (
       SELECT * 
       FROM (
        --get the work center, reporting operation seq, and max reporting op seq for the route 
        SELECT base.site, base.shop_order,base.sfc, base.router, base.router_revision, 
        base.completeDateTime ,base.operation, base.work_center, cf.value rep_op_seq 
        , row_number() over (partition by base.shop_order, base.sfc, base.router, base.router_revision, base.operation, base.work_center order by base.shop_order) rownumber 
        , MAX(cf.value) OVER (PARTITION BY base.work_center) AS max_wc_op_rpt_seq 
        , MAX(cf.value) OVER (PARTITION BY base.work_center)+1 AS max_wc_op_rpt_seqPlus 
        FROM (
          --get only completes during the filtered time for the active shop orders 
          SELECT DISTINCT al.site, al.router, al.router_revision, al.sfc, 
          al.activity, al.reporting_center_bo 
            ,substr(al.shop_order_bo,instr(al.shop_order_bo, '','') + 1,length(al.shop_order_bo) - instr(al.shop_order_bo, '','')) shop_order 
            ,(al.date_time + to_number(concat(substr(extract(TIMEZONE_OFFSET from systimestamp), 1, 1), substr(extract(TIMEZONE_OFFSET from systimestamp), 12, 2)))/24) completeDateTime 
          , substr(o.reporting_center_bo,instr(o.reporting_center_bo, '','') + 1,length(o.reporting_center_bo)) work_center 
         , o.handle oHandle 
         , o.operation           
        FROM 
        wip.activity_log al, 
        wip.operation o 
        WHERE 
        al.action_code = ''COMPLETE'' 
        AND al.operation = o.operation 
        AND al.site = ''' + @site + ''' 
          -- AND trunc(al.date_time + to_number(concat(substr(extract(TIMEZONE_OFFSET from systimestamp), 1, 1), substr(extract(TIMEZONE_OFFSET from systimestamp), 12, 2)))/24) 
          -- <= TO_DATE(''' + @goalDate + ''',''yyyy/mm/dd'') 

        AND substr(al.shop_order_bo,instr(al.shop_order_bo, '','') + 1,length(al.shop_order_bo) - instr(al.shop_order_bo, '','')) 
            = ''' + @so + ''' 
      ) base 
       ,wip.router r , wip.router_step rs, wip.router_operation ro 
       ,(SELECT SUBSTR(handle,instr(handle, '','') + 1,length(handle) - instr(handle, '','') - 2) operation, attribute, value 
        FROM wip.custom_fields 
        WHERE attribute = ''REPORT_OP_SEQUENCE'') cf 
       WHERE 
       base.router = r.router (+)  
       AND base.router_revision = r.revision (+)  
       AND r.handle = rs.router_bo (+) 
       AND rs.handle = ro.router_step_bo (+) 
       AND substr(ro.operation_bo,1,length(ro.operation_bo)-2) = substr(base.oHandle,1,length(base.oHandle)-2) 
       AND base.operation = cf.operation (+) 
       AND base.work_center = ''' + @wc2 + ''' 
     ) 
       WHERE rownumber = 1       
     ) 
     WHERE rep_op_seq = max_wc_op_rpt_seq 
    )' 


      SET @openQueryStr = 'select * into ##tmp_tbl FROM OPENQUERY(WIP, ''' + REPLACE(@sqlStr, '''', '''''') + REPLACE(@sqlStr2, '''', '''''') + ''')' 
      EXEC(@openQueryStr)  
     --print @sqlStr 
     --print @sqlStr2 


       UPDATE goal 
       SET actual_yield = t.wc_outs, 
       actual_yield_to_need_date = t.WC_OUTS_TO_NEED_DATE 
       FROM goal g inner join ##tmp_tbl t ON g.shop_order = t.shop_order 
        AND g.work_center = Right(t.work_center, LEN(t.work_center)-4) 
        AND g.goal_date = t.goal_date 





    ---------------------------IF THERE IS AN EARLY GOAL, THEN GET THE OUTS FOR THAT GOAL up to the early goal date-------------- 

    IF (@early_goal_date IS NOT NULL) 
    BEGIN 
      IF OBJECT_ID('tempdb..##tmp_tbl') IS NOT NULL 
      DROP TABLE ##tmp_tbl 


    set @sqlStr = 'SELECT DISTINCT site, shop_order 
    , work_center, ''' + @early_goal_date + ''' as goal_date, 
     COUNT(*) OVER (PARTITION BY shop_order, work_center ORDER BY shop_order) WC_OUTS 
    FROM (
      SELECT * 
      FROM (
         SELECT base.site, base.shop_order, base.sfc, base.router, base.router_revision, 
         base.completeDateTime ,base.operation, base.work_center, cf.value rep_op_seq 
         , row_number() over (partition by base.shop_order, base.sfc, base.router, base.router_revision, base.operation, base.work_center order by base.shop_order) rownumber          
         , MAX(cf.value) OVER (PARTITION BY base.work_center) AS max_wc_op_rpt_seq 
         , MAX(cf.value) OVER (PARTITION BY base.work_center)+1 AS max_wc_op_rpt_seqPlus 
         FROM (
           SELECT DISTINCT al.site, al.router, al.router_revision, al.sfc, 
           al.activity, al.reporting_center_bo 
           ,substr(al.shop_order_bo,instr(al.shop_order_bo, '','') + 1,length(al.shop_order_bo) - instr(al.shop_order_bo, '','')) shop_order 
           ,(al.date_time + to_number(concat(substr(extract(TIMEZONE_OFFSET from systimestamp), 1, 1), substr(extract(TIMEZONE_OFFSET from systimestamp), 12, 2)))/24) completeDateTime 
         , substr(o.reporting_center_bo,instr(o.reporting_center_bo, '','') + 1,length(o.reporting_center_bo)) work_center 
         , o.handle oHandle 
         , o.operation 
         FROM 
         wip.activity_log al, 
         wip.operation o 
         WHERE 
         al.action_code = ''COMPLETE'' 
         AND al.operation = o.operation 
         AND al.site = ''' + @site + ''' 
         AND trunc(al.date_time + to_number(concat(substr(extract(TIMEZONE_OFFSET from systimestamp), 1, 1), substr(extract(TIMEZONE_OFFSET from systimestamp), 12, 2)))/24) 
         <= TO_DATE(''' + @early_goal_date + ''',''yyyy/mm/dd'') 

         AND substr(al.shop_order_bo,instr(al.shop_order_bo, '','') + 1,length(al.shop_order_bo) - instr(al.shop_order_bo, '','')) 
             = ''' + @so + ''' 
       ) base 
        ,wip.router r , wip.router_step rs , wip.router_operation ro 
        ,(SELECT SUBSTR(handle,instr(handle, '','') + 1,length(handle) - instr(handle, '','') - 2) operation, attribute, value 
         FROM wip.custom_fields 
         WHERE attribute = ''REPORT_OP_SEQUENCE'') cf 
        WHERE 
        base.router = r.router (+)  
        AND base.router_revision = r.revision (+)  
        AND r.handle = rs.router_bo (+) 
        AND rs.handle = ro.router_step_bo (+) 
        AND substr(ro.operation_bo,1,length(ro.operation_bo)-2) = substr(base.oHandle,1,length(base.oHandle)-2) 
        AND base.operation = cf.operation (+) 
        AND base.work_center = ''' + @wc2 + ''' 
      ) 
      WHERE rownumber = 1          
    ) 
    WHERE rep_op_seq = max_wc_op_rpt_seq 
    ORDER BY shop_order, work_center' 


      SET @openQueryStr = N'select * into ##tmp_tbl FROM OPENQUERY(WIP, ''' + REPLACE(@sqlStr, '''', '''''') + ''')' 
      EXEC(@openQueryStr)  
      --print @sqlStr 

       UPDATE goal 
       SET early_actual_yield_to_need_date = t.wc_outs 
       FROM goal g inner join ##tmp_tbl t ON g.shop_order = t.shop_order 
        AND g.work_center = Right(t.work_center, LEN(t.work_center)-4) 
        AND g.early_goal_date = t.goal_date 
      END 
    ---------------------------------------------------------------------------------------------------------      




      IF OBJECT_ID('tempdb..##tmp_tbl') IS NOT NULL 
      DROP TABLE ##tmp_tbl 

      FETCH NEXT FROM db_cursor INTO @so, @wc, @goalDate, @goal_yield, @early_goal_yield, @early_goal_date 
    END 

    CLOSE db_cursor 
    DEALLOCATE db_cursor 

     END 
    END 



    --[sp_GetGoaling_Outs] 'OR01' 
+4

「グローバル」一時表と「ローカル」一時表を使用する必要があるのはなぜですか?ジョブが15分ごとに実行されるようにスケジュールされ、グローバルな一時テーブルが関与して45分間実行されると、あまりにも多くのことが間違ってくる可能性があります(コードを呼び出すコードによって異なります)。 – DVT

+0

ジョブがオフのときに正常に実行されますか? 1つのプロセスがすでに##テーブルを使用している間に後続のジョブが失敗することが予想されますが、グローバルに理由がない限り、私はローカルのtempに切り替えます。 –

+2

サイドノート:ストアドプロシージャのプレフィックス 'sp_'を**使用しないでください**。マイクロソフトは、[*ストアドプロシージャの名前付け*を参照してください](http://msdn.microsoft.com/en-us/library/ms190669%28v=sql.105%29.aspx)、およびあなたはいつか名前衝突のリスクを将来実行します。 [ストアドプロシージャのパフォーマンスにも悪い](http://www.sqlperformance.com/2012/10/t-sql-queries/sp_prefix)単に 'sp_'を避け、他の何かを接頭辞として使うのが最善です。 –

答えて

0

あなたは絶対にそのテーブルがtmp_tblが、グローバル・テンポラリ・テーブルにはあま​​りにも一般的なもので##名sp--

BEGIN TRY 
    drop table ##tmp_tbl 
END TRY 
BEGIN CATCH 
    /* table does not exist */ 
END CATCH 
+0

これは正常に実行されましたが、45分かかった – user3597849

+0

これは通常、データベースエンジンチューニングアドバイザを使用してこのクエリを実行しましたか? – pizzaslice

+0

いいえ私はしていない!それが何なのか分かりません!通常のクエリは2分で実行されます。これらのクエリをページ上に追加/削除する唯一の違いを長時間かけて行っています – user3597849

1

を開始する前に削除したい場合たぶんあなたのプロセスと重複して同じ名前を使用しているサーバー上の別のプロセスでしょう。

は、私はあなたが動的SQL内でそれを作成しているので、あなたがグローバルな一時テーブルを使用する必要があることを理解すなわち## tmp_sp_GetGoaling_Outs

0

あなたのプロセスに固有のものに##テーブルの名前を変更してください。しかし、私は##30 tbl_tbl をカーソルの中に作成して削除していることに気付きました。 私はあなたがそのようなあなたのカーソルインサイド次

if object_id('tempdb..##temp_tbl') is not null 
    drop table ##temp_tbl; 

create table ##temp_tbl (....) 

としてカーソルの外このグローバル一時テーブルを作成することをお勧めします、あなたの代わりに

select .. into ##temp_tbl from ... 
を使用するのでは、あなたの動的なクエリを再書き込みする必要があります

私は目をやろうとしたときに表示されるエラーは、カーソル内でおそらく疑い

truncate table ##temp_tbl; 
insert into ##temp_tbl (...) 
select ... from 

を使用して* ## temp_tblに*を選択します。

+0

私はこのストアドプロシージャを編集しなければならない特定の方法はありますか? IEのジョブを停止し、プロシージャを更新し、ジョブを再開します。またはそれは15分ごとに実行されるため、実行の間に変更を行いますか? – user3597849

関連する問題