You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL存储过程中如何验证XML节点格式并抛出专属错误?

问题描述

我有个上传按钮用来上传XML文件并在网格展示,同时有个存储过程接收带指定<group></group>节点的XML参数。但上传包含<anythingelse></anythingelse>这类非指定节点的XML时,存储过程没法正常处理,还会抛出和重复值一样的错误。现在需要加条件,让XML格式错误时抛出专属提示。

原存储过程代码如下:

CREATE PROCEDURE xml_data          
    @xml XML ,     
    @group varchar(50) = NULL,
AS         
    CREATE TABLE #XMLTble 
    (    
        [group] varchar(50),    
    )    
    
BEGIN     
    DECLARE @count numeric;    

    SET @count = (SELECT COUNT(1) FROM table_t1 

    SET NOCOUNT ON;          

    INSERT INTO #XMLTble ([group])         
        SELECT  
            Configuration.value('(Group/text())[1]', 'VARCHAR(max)') AS [group]    
            FROM @xml.nodes('/Merchant/Configuration') AS TEMPTABLE(Configuration)    
  
    DELETE #XMLTble 
    FROM #XMLTble xc 
    INNER JOIN table_t1 gp ON xc.[group] = gp.[group];
   
    INSERT INTO table_t1    
        SELECT * 
        FROM #XMLTble     
    
    IF ((SELECT COUNT(1) FROM table_t1 
    BEGIN      
        RAISERROR('Duplicated xml values',16,1);      
        RETURN      
    END      
END 

现在只有重复值的判断条件,传格式不对的XML会报一样的错,得解决这个问题。

解决方案

要区分XML格式错误和重复值错误,直接修改存储过程即可,核心是添加两层格式校验逻辑:

  1. 检查XML中是否存在非指定的节点
  2. 确保每个预期的父节点下都包含必要的<Group>节点

修改后的完整代码:

CREATE PROCEDURE xml_data          
    @xml XML,     
    @group varchar(50) = NULL
AS         
    CREATE TABLE #XMLTble 
    (    
        [group] varchar(50)
    )    
    
BEGIN     
    SET NOCOUNT ON;
    DECLARE @invalidNodes INT;
    DECLARE @configNodeCount INT;
    DECLARE @groupNodeCount INT;

    -- 检查是否存在非<Group>的子节点
    SELECT @invalidNodes = COUNT(*)
    FROM @xml.nodes('/Merchant/Configuration/*') AS TEMPTABLE(Node)
    WHERE Node.value('local-name(.)', 'VARCHAR(100)') <> 'Group';

    IF @invalidNodes > 0
    BEGIN      
        RAISERROR('XML格式错误:包含未允许的节点', 16, 1);      
        RETURN;      
    END

    -- 确保每个<Configuration>下都有<Group>节点
    SELECT @configNodeCount = COUNT(*)
    FROM @xml.nodes('/Merchant/Configuration') AS TEMPTABLE(Config);

    SELECT @groupNodeCount = COUNT(*)
    FROM @xml.nodes('/Merchant/Configuration/Group') AS TEMPTABLE(GroupNode);

    IF @configNodeCount <> @groupNodeCount
    BEGIN      
        RAISERROR('XML格式错误:部分<Configuration>节点缺少<Group>子节点', 16, 1);      
        RETURN;      
    END

    -- 原有数据处理逻辑(修正原代码语法问题)
    INSERT INTO #XMLTble ([group])         
        SELECT  
            Configuration.value('(Group/text())[1]', 'VARCHAR(50)') AS [group]    
        FROM @xml.nodes('/Merchant/Configuration') AS TEMPTABLE(Configuration)    

    -- 删除已存在的重复数据
    DELETE #XMLTble 
    FROM #XMLTble xc 
    INNER JOIN table_t1 gp ON xc.[group] = gp.[group];
   
    -- 插入新数据到正式表
    INSERT INTO table_t1    
        SELECT * 
        FROM #XMLTble     
    
    -- 重复值检查(修正原代码语法错误)
    DECLARE @originalTableCount INT;
    SELECT @originalTableCount = COUNT(1) FROM table_t1;
    
    -- 校验插入后数据是否符合预期,判断是否存在重复
    IF @originalTableCount <> (SELECT COUNT(1) FROM table_t1) + (SELECT COUNT(1) FROM #XMLTble)
    BEGIN      
        RAISERROR('Duplicated xml values', 16, 1);      
        RETURN;      
    END      
END 
关键说明
  • 非指定节点检测:通过遍历/Merchant/Configuration下的所有子节点,筛选出名称不是Group的节点,只要存在就直接抛出格式错误。
  • 必要节点校验:对比Configuration节点总数和其中包含的Group节点数,确保一一对应,避免出现缺少Group的无效XML。
  • 修复原代码问题:原存储过程存在未闭合的IF语句、变量定义后语法错误,这些问题已一并修正。

内容的提问来源于stack exchange,提问作者Freshernoob

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 21:25:17