Sql server 如何在具有长结果的查询中尝试\u cast错误处理

Sql server 如何在具有长结果的查询中尝试\u cast错误处理,sql-server,error-handling,try-cast,Sql Server,Error Handling,Try Cast,我试图找出如何捕捉错误,并找出其中一个try_cast何时返回null。存储过程中的查询如下所示: SELECT try_cast(ORI.body AS xml).value('(/BODY/@formid)[1]', 'INT') AS 'Form ID' , try_cast(ORI.body AS xml).value('(/BODY/@form_answers)[1]', 'NVARCHAR(MAX)') AS 'Body' ,

我试图找出如何捕捉错误,并找出其中一个try_cast何时返回null。存储过程中的查询如下所示:

   SELECT
          try_cast(ORI.body AS xml).value('(/BODY/@formid)[1]', 'INT') AS 'Form ID'
        , try_cast(ORI.body AS xml).value('(/BODY/@form_answers)[1]', 'NVARCHAR(MAX)') AS 'Body'
        , ORN.info_id
        , getdate() as create_date
    FROM
        ORG_NOTEPAD ORN
    INNER JOIN
        ORG_INFO ORI ON ORN.info_id = ORI.id
    WHERE 
        COALESCE(ORI.template_id,0)<>0 
    AND 
        COALESCE(ORN.case_id,0)<> 0 
    AND 
        ORN.type_id <> 4
这个查询返回大约800行。在这个示例中有3个单独的try类型转换

我知道每个try_cast都可以返回null,但它们中的任何一个都可以返回错误消息。如何运行此查询,同时查找任何返回null或错误消息的try\u cast结果?我需要获得结果中包含null或错误消息的详细信息,如info_id和form id,并将错误信息和上下文写入错误表。但是我还要把好的结果写在一个单独的表中

我发现了很多,但在这方面,我需要捕获更多关于空消息或错误消息的个人信息。我找到的最接近的东西是,但是我在将这些信息应用到我的示例中时遇到了问题

我不确定我是否需要使用case语句和带有单个try_cast的temp表,或者关于错误处理/null/good answer处理


我对存储过程比较陌生,还尝试了\u cast等。谢谢您的帮助。

FYI,不要在WHERE中的列上使用COALESCE,这会使查询变得不可搜索。使用正确的布尔逻辑并处理空值。关于你的问题,我不确定我是否理解。试一试不会出错;这就是重点。如果无法转换该值,它将返回NULL。如果该值已经为NULL,它也将返回NULL。
create table #ORG_INFO
(
id int identity(1,1),
body nvarchar(max)
);

insert into #ORG_INFO(body)
values
(N'<BODY formid="1234"/>'),
(NULL), --just null
(N'<BODY>'), --invalid xml
(N'<BODY formid="abcd"/>'), --formid not a number
(N'<BODY anotherattrib="1234"/>'); --missing @formid

select 
case 
    when body is null then cast('body is null' as varchar(100))
    when try_cast(body as xml) is null then 'invalid xml'
    when try_cast(body as xml).exist('/BODY/@formid') = 0 then 'missing formid'
    when try_cast(body as xml).exist('xs:integer((/BODY/@formid)[1])') = 0 then 'non-numeric formid'
    else 'ok'   
end as ctrlmsg,
try_cast(body as xml).value('xs:integer((/BODY/@formid)[1])', 'int') as formid,
*
from #ORG_INFO;


drop table #ORG_INFO;