0

テキストとして保存された式の形式でカスタム検証基準を含む SQL Server 2008 のテーブルがあります。

StagingTableID    CustomValidation
----------------------------------
1                 LEN([mobile])<=30
3                 [Internal/External] IN ('Internal','External')
3                 ([Internal/External] <> 'Internal') OR (LEN([Contact Name])<=100)
...

テーブル内のすべての行が条件ステートメントを通過するかどうかを判断したいと考えています。この目的のために、特定のテーブルの特定のフィールドのすべての値が特定の条件を満たしているかどうかをチェックする検証ストアド プロシージャを作成しています。SQL は私の得意分野ではないため、この質問を読んだ後、これが私の最初の問題です。

EXEC sp_executesql N'SELECT @passed = 0 WHERE EXISTS (' +
                     N'SELECT * FROM (' +
                       N'SELECT CASE WHEN ' + @CustomValidationExpr + N' THEN 1 ' +
                       N'ELSE 0 END AS ConditionalTest ' +
                       N'FROM ' + @StagingTableName +
                     N')t ' +
                     N'WHERE t.ConditionalTest = 0)'
                  ,N'@passed BIT OUTPUT'
                  ,@passed = @PassedCustomValidation OUTPUT

ただし、ネストされたクエリを 1 つとして書き直すことができるかどうか、またはこのシナリオですべての行の有効性をテストするためのより良い方法があるかどうかはわかりません。

前もって感謝します!

4

3 に答える 3

1

元の質問に答える前に、制約の実装を検討しましたか?これにより、最初から不正なデータがデータベースに入るのを防ぐことができます。それとも、これらをアプリケーションで動的に設定する必要があるという点ですか?

ALTER TABLE StagingTable
    WITH CHECK ADD CONSTRAINT [StagingTable$MobileValidLength]
    CHECK (LEN([mobile])<=30)
GO

ALTER TABLE StagingTable
    WITH CHECK ADD CONSTRAINT [StagingTable$InternalExternalValid]
    CHECK ([Internal/External] IN ('Internal','External'))
GO

--etc...
于 2012-12-20T15:26:12.830 に答える
1

次のように、少なくとも 1 つのサブクエリを減らすことができるはずです。

EXEC sp_executesql N'SELECT @passed = 0 WHERE EXISTS (' +
                       N'SELECT 1 FROM ' +  @StagingTableName +
                       N'WHERE NOT(' + @CustomValidationExpr + N')) ' +
                  ,N'@passed BIT OUTPUT'
                  ,@passed = @PassedcustomValidation OUTPUT
于 2012-12-20T15:28:37.517 に答える
0

式を連結する必要があります。私は@PinnyMに同意します。これwhereは、完全なテーブル検証では句の方が簡単であるということです。ただし、次の質問は、どの行がどのテストに失敗したかを特定する方法です。私はあなたがそれに答える前にその質問をするのを待ちます(これに対する編集としてではなく、別の質問としてそれを尋ねてください)。

句を作成するにはwhere、次のようにします。

declare @WhereClause nvarchar(max);
select @WhereClause = (select CustomValidation+' and '
                       from Validations v
                       for xml path ('')
                      ) + '1=1'

select @WhereClause = replace(replace(@WhereClause, '&lt;', '<'), '&gt;', '>'))

と二重選択を使用したこの奇妙な構成は、for xml path('')SQLServerで値を連結するための最も便利な方法です。

また、 sp_executesql呼び出しを実行する前に、クエリをまとめてください。それはあなたにもっと柔軟性を与えます:

declare @sql nvarchar(max);
select @sql = '
select @passed = count(*)
from '+@StagingTableName+'
where '+@WhereClause

これは、すべての検証テストに合格した数です。失敗のwhere条項は次のとおりです。

declare @WhereClause nvarchar(max);
select @WhereClause = (select 'not '+CustomValidation+' or '
                       from Validations v
                       for xml path ('')
                      ) + '1=0'
于 2012-12-20T16:11:29.217 に答える