私の会社には、 XML であるはずVARCHAR(N)
の文字列が配置されている列を含むログ テーブルがありますが、実際には、常に適切な形式であるとは限りません。ロギングの分析 (エラーの傾向の特定など) を実行するために、ステートメントを使用しています。ただし、これは非常に遅いです。LIKE
最近、SQL Server が XQuery をサポートしていることを発見したので、それで遊んでみました。私が直面している問題は、ステートメントCAST/CONVERT
内のエラーを処理する方法がわからないことです。SELECT
私が最も近いのは、TRY_CONVERT
機能があるためSQL Server 2012が必要ですが、2008 R2からのアップグレードは現在オプションではありません.
これが私が持っているものです(私の会社が2012年を運営していればうまくいくでしょう):
CREATE FUNCTION IsMatch(
@message AS VARCHAR(MAX),
@match AS VARCHAR(MAX),
@default AS VARCHAR(MAX))
RETURNS VARCHAR(MAX)
AS
BEGIN
DECLARE @xml XML = TRY_CONVERT(XML, @message)
DECLARE @result VARCHAR(MAX) =
CASE WHEN @xml IS NOT NULL
THEN CASE WHEN @xml.exist('(/FormattedMessage)[contains(.,sql:variable("@match"))]') = 1
THEN @match
ELSE @default
END
ELSE CASE WHEN @message LIKE '%' + @match + '%'
THEN @match
ELSE @default
END
END
RETURN @result
END
GO
DECLARE @search VARCHAR(MAX) = 'a substring of my xml error message'
SELECT Error, COUNT(*) as 'Count'
FROM ( SELECT TOP 319 [LogID]
,[Severity]
,[Title]
,[Timestamp]
,[MachineName]
,[FormattedMessage]
--,CAST([formattedmessage] as xml)
,IsMatch(@search, 'Other') as 'Error'
FROM [MyDatabase].[dbo].[Log] (NOLOCK) ) a
GROUP BY Error
コメントCAST
(または代わりにCONVERT
) は、不正な形式の XML に遭遇するとすぐにクエリをエラーにします。TOP (N) に制限すると、エラーがなく、SELECT
ステートメントが信じられないほど高速に動作することが保証されます。行ごとにエラーを処理する方法が必要なだけです。
TRY/CATCH
inの使用を検討しましたIsMatch()
が、関数では使用できません。または、 を使用するために、ストアド プロシージャを検討しましたが、それを句TRY/CATCH
に含める方法がわかりません。SELECT