0

我正在尝试设计一个查询来搜索 EMR 数据库中的审计日志。问题是审计信息存储在 varchar 列中,有时它只是对发生的事情的文本描述(我不在乎),有时它包含有效的 XML(我知道这是一个设计缺陷,但我可以'不要改变它,因为我没有创建 EMR)

我创建了一个表值函数来解析 xml 并返回数据,但是 select 语句无法执行,因为有时函数中的 xml 转换会失败。我不能对函数中的转换进行 try/catch,我也可以从函数调用存储过程来使用 try/catch 进行转换,所以我不知道该去哪里。

select top 1 * from Audit with(nolock) external apply dbo.cus_GetDeletedAttachmentInfo(Audit.Audituid) as detail

错误 XML 解析:第 1 行,字符 136,非法 xml 字符

4

2 回答 2

1

您的标记中有一个非法字符,您在尝试转换为 xml 时可能需要注意。我做了这样的事情:

declare @Text varchar(max);

select @Text = '<root><stuff>&</stuff></root>'


begin try
    select Cast(@Text as xml)
end try
begin catch
    Select Error_message()

    Select 'Let''s account for ampersand manually by converting'

    select cast(replace(@Text, '&', '&amp;') as xml)
end catch

您需要考虑诸如与号和其他未标记的字符之类的内容,否则 SQL Server 中强制转换或转换的默认行为会失败并说明失败的原因。XML 需要标记特殊字符。通常有像这里这样的标记列表(没有尝试过所有这些,因为这只是一个例子):

http://rabbit.eng.miami.edu/info/htmlchars.html

于 2013-05-02T16:23:55.513 回答
0

对于http://rabbit.eng.miami.edu/info/htmlchars.html中提到的所有这些字符,它并没有失败

我检查了以下两组。只有第 2 套有问题

SELECT
    cast( 
        REPLACE(
        REPLACE(fldvalue,'<', '&lt;')
        ,'&','&amp;')
        
         as xml) 
    
FROM
(
    -- set 1
    select fldvalue = '<abc>test</abc>' -- Pure text
    UNION
    select fldvalue = '<abc>$test</abc>' -- with $ symbol
    union
    select fldvalue = '<abc>%test</abc>' -- with % symbol
    UNION
    select fldvalue = '<abc>>1test</abc>' -- with > symbol
    UNION
    select fldvalue = '>>1test' -- with >> symbol
    UNION
    select fldvalue = '<abc>test"</abc>' -- with " symbol
    UNION
    select fldvalue = '¢test' -- with ¢ symbol
    UNION
    select fldvalue = '£test' -- with £ symbol
    UNION
    select fldvalue = '¥test' -- with ¥ symbol
    UNION
    select fldvalue = '©test' -- with © symbol
    UNION
    select fldvalue = '½test'  -- with ½ symbol
    
    
    -- set 2
    UNION
    select fldvalue = '<def><test</def>'
    UNION
    select fldvalue = '&1test'
    
) A
于 2020-09-11T14:49:01.883 回答