0

将来の日付 (土日を除く) を永続テーブルに挿入するストアド プロシージャを作成しました。ルーチンは 1 つの一時テーブルのみを使用します。この投稿の目的は、ストアド プロシージャを批判することではありません。ただし、改善できると確信しています。ただし、この投稿の目的は、ストアド プロシージャが特定の状況で呼び出されたときにこれらのエラーをスローし、他の状況ではスローしない理由を分析することです。

1 - 受け取ったエラーは次のとおりです

Msg 207, Level 16, State 1, Procedure MAKE_FUTURE_DATES, Line 25
Invalid column name 'tdate'.
Msg 207, Level 16, State 1, Procedure MAKE_FUTURE_DATES, Line 31
Invalid column name 'wday'.

2 - ストアド プロシージャは次のとおりです。

ALTER PROCEDURE [dbo].[MAKE_FUTURE_DATES] (@STARTDATE DATE)
AS
BEGIN
-- We need to populate FUTURE_DATES (table) with forward looking dates (week days only) 
-- We do not consider/exclude holidays here. We just exclude Sat/Suns

-- Temp table to hold the dates and days of the week
    CREATE TABLE #TMP_DATES(
        [tdate] [date] NULL,
        [wday] [varchar](10) NULL,  
        )

    -- To generate 'enough' future dates loop up to 1199 days in the future
    -- and insert dates that start with the current date and increase with each loop

    DECLARE @Loop INT
    SET @Loop = 0
    WHILE @Loop < 1200
    BEGIN
        INSERT INTO #TMP_DATES (tdate) VALUES (DATEADD(weekday,@Loop,@STARTDATE))   
        SET @Loop = @Loop + 1
    END

    -- Now update the wday column with the weekday name so we can get rid of
    -- Sat/Sun in the next step

    UPDATE #TMP_DATES
    SET wday = UPPER(LEFT(DATENAME(dw,tdate),3))

    -- Get rid of Sat/Sun
    DELETE FROM #TMP_DATES WHERE wday = 'SAT' or wday = 'SUN'

    -- Now clear the final destination table
    TRUNCATE TABLE FUTURE_DATES

    -- Insert the weekday dates into future_dates

    INSERT INTO FUTURE_DATES (fdate,wday)
    SELECT tdate,wday FROM #TMP_DATES

    DROP TABLE #TMP_DATES

3 - 上記のストアド プロシージャを別のストアド プロシージャ内で SQL Server タスクとしてバックグラウンドで (SQL Server ジョブ スケジューラ経由で) 約 6 か月間呼び出しましたが、エラーや問題は発生しませんでした。最近、MAKE_FUTURE_DATEs を呼び出すストアド プロシージャを呼び出す新しいストアド プロシージャを作成しました。これを「ABC」と呼びましょう。

4 - これが私が解決しようとしている部分です。バックグラウンドで (SQL Server ジョブ スケジューラを介して) ABC が SQL Server タスクとして呼び出されると、毎回 (毎日) エラーがスローされ、結果が生成されないかクラッシュします。初めて SQL Server Management Studio を起動して ABC を実行すると、最初にエラーがスローされることがあります。このシーケンスの 2 回目以降は、エラーは発生しません。また、6 か月間 MAKE_FUTURE_DATES を呼び出してきたストアド プロシージャは、エラーが発生せずに満足していることにも注意してください。

これをデバッグする方法や何を探すべきかについての提案を探しています。特に、他のエラーではなく、時々エラーをスローするにはどうすればよいですか?

4

2 に答える 2

8

あなたが投稿したコードは私にはうまく見えます。これは完全なコードですか?

頭に浮かぶ唯一のことは、「ABC」ストアド プロシージャにも #TMP_DATES という一時テーブルがあることです。ABC の一時テーブルは、呼び出されたストアド プロシージャのスコープでも使用できます。

ただし、その場合はCREATE TABLE #TMP_DATES、呼び出されたプロシージャで呼び出したときに別のエラーが発生するはずです。

于 2013-11-12T20:20:15.953 に答える
1

一時テーブルのスコープは、1 つのプロシージャよりも大きくなります。

したがって、uspProc1 で一時テーブルを作成できます...そして、uspProc1 で uspProc2 を呼び出すと、uspProc2 は作成した一時テーブルを「見ることができます」。

#temp テーブルには必ず一意の名前を付けてください。

以下は、その点を示す例です。

IF EXISTS 
    (
    SELECT * FROM INFORMATION_SCHEMA.ROUTINES
    WHERE ROUTINE_TYPE = N'PROCEDURE' and ROUTINE_SCHEMA = N'dbo' and ROUTINE_NAME = N'uspProc001'  
    )
BEGIN
    DROP PROCEDURE [dbo].[uspProc001]
END


GO

CREATE Procedure dbo.uspProc001 (
@Param1 int
)
AS

BEGIN


IF OBJECT_ID('tempdb..#TableOne') IS NOT NULL
begin
        drop table #TableOne
end


CREATE TABLE #TableOne
( 
SurrogateKey int , 
NameOf varchar(12)
)

Insert into #TableOne ( SurrogateKey , NameOf ) select 1001, 'uspProc001'

Select * from #TableOne

EXEC dbo.uspProc002 

Select * from #TableOne

IF OBJECT_ID('tempdb..#TableOne') IS NOT NULL
begin
        drop table #TableOne
end


END


GO




IF EXISTS 
    (
    SELECT * FROM INFORMATION_SCHEMA.ROUTINES
    WHERE ROUTINE_TYPE = N'PROCEDURE' and ROUTINE_SCHEMA = N'dbo' and ROUTINE_NAME = N'uspProc002'  
    )
BEGIN
    DROP PROCEDURE [dbo].[uspProc002]
END


GO

CREATE Procedure dbo.uspProc002 
AS

BEGIN

IF OBJECT_ID('tempdb..#TableOne') IS NOT NULL
begin
    Insert into #TableOne ( SurrogateKey , NameOf ) select 2001, 'uspProc002'
end



END


GO










exec dbo.uspProc001 0
于 2013-11-12T20:28:58.633 に答える