跳过读取SQL Server存储过程中的XML元素
我在SQL Server 2016中有一个读取XML文件的存储过程。如果没有值,我想做的是跳过保存元素 XML元素应该如下所示跳过读取SQL Server存储过程中的XML元素,xml,stored-procedures,sql-server-2016,Xml,Stored Procedures,Sql Server 2016,我在SQL Server 2016中有一个读取XML文件的存储过程。如果没有值,我想做的是跳过保存元素 XML元素应该如下所示 <PROJECT_TERMSX> <TERM>Extramural Activities</TERM> <TERM>programs</TERM> <TERM>research facility</TERM> </PROJECT_TERMSX&g
<PROJECT_TERMSX>
<TERM>Extramural Activities</TERM>
<TERM>programs</TERM>
<TERM>research facility</TERM>
</PROJECT_TERMSX>
我想跳过具有http模式但不知道如何构造代码的元素。我无法控制原始XML结构。您就快到了。XPath表达式.nodes('/PROJECT\u TERMSX/TERM')
将过滤掉不需要的带有空值的XML
SQL
有时标准化可以帮助您很多,即使需要更多的步骤。在我的例子中,我使用下面的表值函数(见下文)将任何XML文件转换为SQL表,从那里我可以做任何我想做的事情。好的是,我不需要为每个xml更改编写代码,它是动态转换的,我可以将数据作为常规表进行管理 使用: 希望这有帮助
<PROJECT_TERMS xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
INSERT into ADMIN_ExPORTER_TERMS (APPLICATION_ID, TERM)
SELECT
APPLICATION_ID,
nref.value('.','varchar(max)') TERM
FROM
[ADMIN_Exporter_Files_XML]
CROSS APPLY
XMLData.nodes('//PROJECT_TERMSX/TERM') AS R(nref)
WHERE
APPLICATION_ID = @APPLICATION_ID
-- DDL and sample data population, start
DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, APPLICATION_ID INT, xmldata XML);
INSERT INTO @tbl (APPLICATION_ID, xmldata)
VALUES (10, N'<PROJECT_TERMSX>
<TERM>Extramural Activities</TERM>
<TERM>programs</TERM>
<TERM>research facility</TERM>
</PROJECT_TERMSX>')
, (10, N'<PROJECT_TERMSX xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />');
-- DDL and sample data population, end
DECLARE @APPLICATION_ID INT = 10;
--INSERT into ADMIN_ExPORTER_TERMS (APPLICATION_ID, TERM)
SELECT APPLICATION_ID
, col.value('(./text())[1]','VARCHAR(MAX)') AS TERM
FROM @tbl AS tbl
CROSS APPLY tbl.XMLData.nodes('/PROJECT_TERMSX/TERM') AS tab(col)
WHERE APPLICATION_ID = @APPLICATION_ID;
+----------------+-----------------------+
| APPLICATION_ID | TERM |
+----------------+-----------------------+
| 10 | Extramural Activities |
| 10 | programs |
| 10 | research facility |
+----------------+-----------------------+
select * from Utility.FlattenXml('<a>1</a><b></b><c>3</c>')
USE [YOUR_DB]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [Utility].[FlattenXml](@xmlDoc XML)
RETURNS TABLE
AS RETURN
WITH CTE AS (
SELECT
1 AS lvl,
x.value('local-name(.)','NVARCHAR(MAX)') AS Name,
CAST(NULL AS NVARCHAR(MAX)) AS ParentName,
CAST(1 AS INT) AS ParentPosition,
CAST(N'Element' AS NVARCHAR(20)) AS NodeType,
x.value('local-name(.)','NVARCHAR(MAX)') AS FullPath,
x.value('local-name(.)','NVARCHAR(MAX)')
+ N'['
+ CAST(ROW_NUMBER() OVER(ORDER BY (SELECT 1)) AS NVARCHAR)
+ N']' AS XPath,
ROW_NUMBER() OVER(ORDER BY (SELECT 1)) AS Position,
x.value('local-name(.)','NVARCHAR(MAX)') AS Tree,
x.value('text()[1]','NVARCHAR(MAX)') AS Value,
x.query('.') AS this,
x.query('*') AS t,
CAST(CAST(1 AS VARBINARY(4)) AS VARBINARY(MAX)) AS Sort,
CAST(1 AS INT) AS ID
FROM @xmlDoc.nodes('/*') a(x)
UNION ALL
SELECT
p.lvl + 1 AS lvl,
c.value('local-name(.)','NVARCHAR(MAX)') AS Name,
CAST(p.Name AS NVARCHAR(MAX)) AS ParentName,
CAST(p.Position AS INT) AS ParentPosition,
CAST(N'Element' AS NVARCHAR(20)) AS NodeType,
CAST(p.FullPath + N'/' + c.value('local-name(.)','NVARCHAR(MAX)') AS NVARCHAR(MAX)) AS FullPath,
CAST(p.XPath + N'/'+ c.value('local-name(.)','NVARCHAR(MAX)')+ N'['+ CAST(ROW_NUMBER() OVER(PARTITION BY c.value('local-name(.)','NVARCHAR(MAX)')
ORDER BY (SELECT 1)) AS NVARCHAR)+ N']' AS NVARCHAR(MAX)) AS XPath,
ROW_NUMBER() OVER(PARTITION BY c.value('local-name(.)','NVARCHAR(MAX)')
ORDER BY (SELECT 1)) AS Position,
CAST( SPACE(2 * p.lvl - 1) + N'|' + REPLICATE(N'-', 1) + c.value('local-name(.)','NVARCHAR(MAX)') AS NVARCHAR(MAX)) AS Tree,
CAST( c.value('text()[1]','NVARCHAR(MAX)') AS NVARCHAR(MAX) ) AS Value, c.query('.') AS this,
c.query('*') AS t,
CAST(p.Sort + CAST( (lvl + 1) * 1024 + (ROW_NUMBER() OVER(ORDER BY (SELECT 1)) * 2) AS VARBINARY(4)) AS VARBINARY(MAX) ) AS Sort,
CAST((lvl + 1) * 1024 + (ROW_NUMBER() OVER(ORDER BY (SELECT 1)) * 2) AS INT)
FROM CTE p
CROSS APPLY p.t.nodes('*') b(c)), cte2 AS (
SELECT
lvl AS Depth,
Name AS NodeName,
ParentName,
ParentPosition,
NodeType,
FullPath,
XPath,
Position,
Tree AS TreeView,
Value,
this AS XMLData,
Sort,
ID
FROM cte
UNION ALL
SELECT
p.lvl,
x.value('local-name(.)','NVARCHAR(MAX)'),
p.Name,
p.Position,
CAST(N'Attribute' AS NVARCHAR(20)),
p.FullPath + N'/@' + x.value('local-name(.)','NVARCHAR(MAX)'),
p.XPath + N'/@' + x.value('local-name(.)','NVARCHAR(MAX)'),
1,
SPACE(2 * p.lvl - 1) + N'|' + REPLICATE('-', 1)
+ N'@' + x.value('local-name(.)','NVARCHAR(MAX)'),
x.value('.','NVARCHAR(MAX)'),
NULL,
p.Sort,
p.ID + 1
FROM CTE p
CROSS APPLY this.nodes('/*/@*') a(x)
)
SELECT
ROW_NUMBER() OVER(ORDER BY Sort, ID) AS ID,
ParentName, ParentPosition,Depth, NodeName, Position,
NodeType, FullPath, XPath, TreeView, Value, XMLData
FROM CTE2