値をアサートする方法が気に入った場合は、入れ子になったストアド プロシージャでアサートする方法について詳しく説明します。
免責事項:このアプローチは、実稼働システムで最高のパフォーマンスを得るための最良の方法ではありません。すべてのデバッグ アサーションにコメントを付けて、運用システムで選択することをお勧めします。特に、デバッグ選択は、ネストされたテーブル結果が親プロシージャに返されるプロシージャである場合、機能を完全に壊す可能性があります!
最初の例:
ALTER PROC [dbo].[MyTopLevelProc]
@SomeText nvarchar(50),
@SomeNumber bigint
/* >>> parameters only for debug >>> */
/* debug parameters should have always default values and should be last parameters of procedure. it is goog practice because of usage during development/production phase */
, @EnableDebugSelects bit = NULL -- if 1, then table-results will be used for asserting table data for debuging
, @LogIndent int = NULL -- determines indentation of text asserts
/* <<< parameters only for debug <<< */
BEGIN
IF @EnableDebugSelects IS NULL SET @EnableDebugSelects = 0
IF @LogIndent IS NULL OR @LogIndent < 0 SET @LogIndent = 0
/* @SubLogIndent = indentation for nested procedures */
DECLARE @SubLogIndent int = @LogIndent + 1
DECLARE @_CurrentProcName_ nvarchar(255) = '[dbo].[MyTopLevelProc]'
EXEC x.LogStr @LogIndent, 'PROC: ', @_CurrentProcName_, ' >>>' -- asserts start of procedure
EXEC x.LogStr @LogIndent, 'INSERT INTO _some_table_'
INSERT INTO _some_table_ ( ... columns ... )
SELECT ... columns ... FROM _other_table_
EXEC x.LogRowCount @LogIndent, @@ROWCOUNT
EXEC x.LogStr @LogIndent, 'Getting product names ...'
DECLARE @TblProductName TABLE (
ProductID int,
ProductName nvarchar(50)
)
INSERT INTO @TblProductName (ProductID, ProductName)
SELECT ProductID, ProductName FROM _some_product_table_
EXEC x.LogRowcount @LogIndent, @@ROWCOUNT
IF @EnableDebugSelects = 1 BEGIN
-- using the name of table-variable (@TblProductName) as column name is good practise for cases when the table variable has no rows. even from column names you can see which table-variable was selected
SELECT '' AS [@TblProductName], * FROM @TblProductName
END
EXEC x.LogStr @LogIndent, 'Calling nested procedure ...'
DECLARE @Result int
EXEC @Result = [dbo].[AnotherProcedure]
@SomeTextParameter = 'Hello world!',
@SomeNumberParameter = 42,
/* we want pass debug parameters into nested procedures */
@EnableDebugSelects = @EnableDebugSelects,
@LogIndent = @SubLogIndent -- passing increased indentation for text asserts
EXEC x.LogInt @LogIndent, '@Result: ', @Result
EXEC x.LogStr @LogIndent, 'PROC: <<< ', @_CurrentProcName_ -- asserts end of procedure
END
プロシージャx.Log*
は、カスタム スキーマ内のカスタム ストアド プロシージャx
です。ストアド プロシージャの本体は次のようになります。
ALTER PROCEDURE [x].[Log]
@LogIndent int = 0,
@Str nvarchar(max),
@Str2 nvarchar(max) = NULL,
@Str3 nvarchar(max) = NULL,
@Str4 nvarchar(max) = NULL,
@Str5 nvarchar(max) = NULL
AS
BEGIN
DECLARE @Msg nvarchar(max) = ''
IF @LogIndent IS NULL SET @LogIndent = 0
IF @LogIndent > 0 BEGIN
DECLARE @i int = 0
WHILE @i < @LogIndent BEGIN
SET @i = @i + 1
SET @Msg = @Msg + ' '
END
END
IF NOT @Str IS NULL SET @Msg = @Msg + @Str
IF NOT @Str2 IS NULL SET @Msg = @Msg + @Str2
IF NOT @Str3 IS NULL SET @Msg = @Msg + @Str3
IF NOT @Str4 IS NULL SET @Msg = @Msg + @Str4
IF NOT @Str5 IS NULL SET @Msg = @Msg + @Str5
PRINT @Msg
END
他のx.Log*
プロシージャは、次のようなヘルパー プロシージャです。
ALTER PROCEDURE [dbo].[LogInt]
@LogIndent int = 0,
@Num int,
@Prefix nvarchar(max) = NULL,
@Suffix nvarchar(max) = NULL
AS
BEGIN
DECLARE @Result int = 0
DECLARE @Msg nvarchar(max) = ISNULL(CAST(@Num as nvarchar(max)), 'NULL')
EXEC @Result = Log @LogIndent = @LogIndent
, @Str = @Prefix
, @Str2 = @Msg
RETURN @Result
END
これが役立つことを願っています。