gre*_*nis 5 t-sql validation casting xquery-sql
我的公司有一个记录表,其中包含一个VARCHAR(N)列,其中放置了一个应该是XML 的字符串,但事实证明它并不总是格式良好.为了对日志记录进行分析(以识别错误趋势等),我一直在使用LIKE语句.然而,这非常缓慢.
最近,我发现SQL Server支持XQuery,所以我开始玩它.我遇到的问题是我无法找到一种方法来处理CAST/CONVERT我的SELECT声明中的错误.我最接近的是需要SQL Server 2012,因为它具有该TRY_CONVERT功能,但是从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
Run Code Online (Sandbox Code Playgroud)
注释CAST(或者替代地CONVERT)一旦遇到格式错误的XML,就会导致查询出错.如果我限制为TOP(N),我可以确保没有错误,并且SELECT语句工作速度非常快.我只需要一种方法来处理每行错误.
我考虑使用TRY/CATCHin IsMatch(),但不能在函数中使用.或者,要使用TRY/CATCH,我考虑了存储过程,但我无法弄清楚如何在我的SELECT子句中包含它.
如果您卡在 2008 R2 上,我认为您想要做的是在存储过程中使用只读前向游标。然后在 WHILE @@FETCH_STATUS = 0 循环内部使用 TRY CATCH 块。
DECLARE logcursor CURSOR FORWARD_ONLY READ_ONLY FOR
SELECT TOP 319 [LogId]
,[formattedmessage]
FROM [GenesisLogging].[dbo].[Log] (NOLOCK)
OPEN logcursor
FETCH NEXT FROM logcursor
INTO @id, @formattedmessage
WHILE @@FETCH_STATUS = 0
BEGIN
BEGIN TRY
SET @xml = CONVERT(xml, @formattedmessage)
END TRY
BEGIN CATCH
PRINT @id
END CATCH;
FETCH NEXT FROM logcursor
INTO @id, @formattedmessage
END
CLOSE logcursor;
DEALLOCATE logcursor;
Run Code Online (Sandbox Code Playgroud)