微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

tsql – 如何在CAST / CONVERT之前检查VARCHAR(n)格式良好的XML

我的公司有一个包含VARCHAR(N)列的日志表,其中放置了一个应该是 XML的字符串,但事实证明它并不总是格式良好.为了对日志记录进行分析(以识别错误趋势等),我一直在使用LIKE语句.然而,这非常缓慢.

最近,我发现sql Server支持XQuery,所以我开始玩它.我遇到的问题是我无法找到一种方法来处理我的SELECT语句中的CAST / CONVERT错误.我最接近的是需要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

注释的CAST(或者CONVEERT)会在遇到格式错误的XML时立即导致查询出错.如果我限制为TOP(N),我可以确保没有错误,SELECT语句的工作速度非常快.我只需要一种方法来处理每行错误.

我考虑在Ismatch()中使用TRY / CATCH,但不能在函数中使用.或者,要使用TRY / CATCH,我考虑了存储过程,但我无法弄清楚如何在SELECT子句中包含它.

如果您坚持使用2008 R2,我认为您要做的是在存储过程中使用只读前向CURSOR.然后使用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;

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。