0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

SQL Server ストアド作成テンプレート(例外処理、トランザクション内でセーブポイントを使用)

Last updated at Posted at 2021-06-01
ストアド作成テンプレート.sql

USE [NPSDBIF]
GO

/****** Object:  StoredProcedure [dbo].[sp_test]    Script Date: 2021/05/31 21:31:46 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author     : 
-- Create date: 2021
-- Description: xx系IF処理
--              
--              ループ①
--               │        --
--               │
--               ├   ループ②
--               │     │ --
--               │     ├   ループ③
--               │     │  --
-- =============================================

CREATE PROCEDURE [dbo].[sp_test]
             @argCount INT OUTPUT
            ,@argMessage NVARCHAR(4000) OUTPUT
AS
BEGIN
    DECLARE @Count       INT, 
            @Message     NVARCHAR(4000),
            @State       INT,--1 〜 127 ノ任意ノ整数
            @Id          VARCHAR(100),
            @Process     NVARCHAR(100),
            @ExitCode    INT,
            @VCExitCnt1  INT;

BEGIN TRY

    SET @Process='処理概要'
    
    DECLARE @TranCounter INT = @@TRANCOUNT
	-- カーソル定義
    Declare Cur1 CURSOR LOCAL STATIC FOR 
        SELECT *
          FROM #UQ_XXX
    OPEN Cur1--カーソルオープン
    FETCH NEXT FROM Cur1 INTO  @xcsd
    WHILE @@FETCH_STATUS = 0
    -- ========= ●①●【ループ】ループ内ノ実際ノ処理 ①▼▼▼===
    BEGIN
        IF @TranCounter > 0
            SAVE TRANSACTION ProcedureSave
        ELSE 
            BEGIN TRANSACTION

        BEGIN TRY
        
                -- カーソル定義
                Declare Cur2 CURSOR LOCAL STATIC FOR
                    SELECT
                         *
                    FROM #TMP_1
                OPEN Cur2--カーソルオープン
                FETCH NEXT FROM Cur2 INTO  @adfe
                WHILE @@FETCH_STATUS = 0
                -- ========= ●②●【ループ】ループ内ノ実際ノ処理 ②▼▼▼===
				BEGIN
					BEGIN TRY	
						
							--●③●【ループ】 カーソル定義
							Declare Cur3 CURSOR LOCAL STATIC FOR
								SELECT
										*
								FROM #TMP_2;
							OPEN Cur3--カーソルオープン
							FETCH NEXT FROM Cur3 INTO  @asfdasdfa
								WHILE @@FETCH_STATUS = 0
								BEGIN
									BEGIN TRY	
										--asdfasdfasf
                                    END TRY

									BEGIN CATCH
										SELECT @ExitCode = ERROR_NUMBER() ,
											   @Message  = ERROR_MESSAGE(),
											   @State    = ERROR_STATE();  
										-- エラー情報を保持
										
										-- カーソル終了
										IF CURSOR_STATUS('local', 'Cur3') > 0
											BEGIN
												CLOSE Cur3;
												DEALLOCATE Cur3;
											END;
										-- 例外を外側の TRY~CATCH に投げる
										THROW;
									END CATCH
									-- ========= ●③●【ループ】ループ内ノ実際ノ処理 ③▲▲▲===
									--次ノ行ノデータを取得シテ変数ヘ値をセット
									FETCH NEXT FROM Cur3 INTO  @asfdasdfa
								END
							--●③●【ループ】カーソル終了
							IF CURSOR_STATUS('local', 'Cur3') > 0
								BEGIN
									CLOSE Cur3;
									DEALLOCATE Cur3;
								END;
						END   
				
					END TRY

					BEGIN CATCH
						SELECT @ExitCode = ERROR_NUMBER() ,
							   @Message  = ERROR_MESSAGE(),
							   @State    = ERROR_STATE();  

						-- エラー情報を保持
						
						-- カーソル終了
						IF CURSOR_STATUS('local', 'Cur2') > 0
							BEGIN
								CLOSE Cur2;
								DEALLOCATE Cur2;
							END;
						IF CURSOR_STATUS('local', 'Cur3') > 0
							BEGIN
								CLOSE Cur3;
								DEALLOCATE Cur3;
							END;
						-- 例外を外側の TRY~CATCH に投げる
						THROW;
					END CATCH

					FETCH NEXT FROM Cur2 INTO  @adfe
				END
				--●②●【明細ノループ】カーソル終了
				IF CURSOR_STATUS('local', 'Cur2') > 0
					BEGIN
						CLOSE Cur2;
						DEALLOCATE Cur2;
					END;
				--一時TBLをクリア
				
				-- ========= ●②●【明細ノループ】ループ内ノ実際ノ処理 ②▲▲▲===
                
            END
            -- ▲機能ブロック END   : ●②●【明細ノループ】

            IF @TranCounter = 0  
				BEGIN
					COMMIT TRANSACTION
				END
                
        -- ▲▲▲▲▲▲▲▲▲▲ Main処理 END   ①▲▲▲▲▲▲▲▲▲▲
        END TRY

        BEGIN CATCH
            SELECT @ExitCode = ERROR_NUMBER() ,
                   @Message  = ERROR_MESSAGE(),
                   @State    = ERROR_STATE();                        
            
			PRINT 'DEBUG ERROR_MESSAGE()=' + convert(nvarchar(4000),ERROR_MESSAGE())

            IF @TranCounter = 0
				BEGIN
					IF XACT_STATE() <> 0
					BEGIN
						ROLLBACK TRANSACTION
					END
				END
            ELSE
				BEGIN
					IF XACT_STATE() <> -1  
					BEGIN
						ROLLBACK TRANSACTION ProcedureSave
					END
				END
            IF CURSOR_STATUS('local', 'Cur2') > 0
                BEGIN
                    CLOSE Cur2;
                    DEALLOCATE Cur2;
                END;
            IF CURSOR_STATUS('local', 'Cur3') > 0
                BEGIN
                    CLOSE Cur3;
                    DEALLOCATE Cur3;
                END;
           
            -- エラー情報を保持
            
        END CATCH
        --次の行のデータを取得シテ変数ヘ値をセット
        FETCH NEXT FROM Cur1 INTO  @xcsd
	END
	--●①●【ループ】 カーソルを閉ジル
	IF CURSOR_STATUS('local', 'Cur1') > 0
		BEGIN
			CLOSE Cur1;
			DEALLOCATE Cur1;
		END;

    -- ========= ●①●ループ内ノ実際ノ処理 ①▲▲▲===

    --一時ものをクリア
   
    -- 後処理

    IF @CmnExecExitCode<> 0
        BEGIN
            SET @Process='連携後処理  >>>'
            SET @ExitCode = -1
        END

END TRY

BEGIN CATCH
    Select @ExitCode = ERROR_NUMBER() ,
           @Message  = ERROR_MESSAGE();
            
    --
	IF CURSOR_STATUS('local', 'Cur1') > 0
		BEGIN
			CLOSE Cur1;
			DEALLOCATE Cur1;
		END;
     IF CURSOR_STATUS('local', 'Cur2') > 0
        BEGIN
            CLOSE Cur2;
            DEALLOCATE Cur2;
        END;
    IF CURSOR_STATUS('local', 'Cur3') > 0
        BEGIN
            CLOSE Cur3;
            DEALLOCATE Cur3;
        END;
    --一時ものをクリア

END CATCH
    SET @argCount = @Count-- 件数
    SET @argMessage = @Message
    RETURN @ExitCode;
--- プロシージャノ終了
END

GO
テスト良い用例
--====================================================================
BEGIN TRAN
EXEC ストアド作成テンプレート 0 , 'UT-TEST: ストアド作成テンプレート.sql';
select 検証用列 from 検証用TBL
select 検証用列 from 検証用TBL
select 検証用列 from 検証用TBL

ROLLBACK TRAN
--====================================================================
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?