Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 从XML列中选择所有XML节点_Sql Server_Xml_Tsql_Xquery_Sql Server 2016 - Fatal编程技术网

Sql server 从XML列中选择所有XML节点

Sql server 从XML列中选择所有XML节点,sql-server,xml,tsql,xquery,sql-server-2016,Sql Server,Xml,Tsql,Xquery,Sql Server 2016,我有一个带有XML列的表。每个条目的XML结构都是完全平坦的,甚至没有父标记-这是一个条目的示例: <tag1>1.22</tag1> <tag3>5</tag3> <tag12>-1.22</tag> 然后在我这端解析XML。或者我显然可以编写xpath查询来选择列中的标记,这就是我想要的,除了有大约1000个可能的标记名,我不想把它们全部写出来,可能会遗漏一个 简言之,我该如何着手: | ID | XML type c

我有一个带有XML列的表。每个条目的XML结构都是完全平坦的,甚至没有父标记-这是一个条目的示例:

<tag1>1.22</tag1>
<tag3>5</tag3>
<tag12>-1.22</tag>
然后在我这端解析XML。或者我显然可以编写xpath查询来选择列中的标记,这就是我想要的,除了有大约1000个可能的标记名,我不想把它们全部写出来,可能会遗漏一个

简言之,我该如何着手:

| ID | XML type column                |
| 1  | <tag1>1</tag1><tag2>2</tag2>   |
| 2  | <tag2>8</tag2><tag34>1</tag34> |
对于我在数据集中可以找到的任何标记,而不事先知道它们?我也会满足于此:

| ID | tag   | value | 
| 1  | tag1  | 1     |
| 1  | tag2  | 2     |
| 2  | tag2  | 8     |
| 2  | tag34 | 1     |

在MS SQL Server中,使用XML数据类型方法和XQuery相对简单。SQL Server可以在没有根元素的情况下处理XML片段,而不会出现任何问题

您试图实现的是XML分解。尽管您需要知道1个XML元素名或2个XML元素名的顺序位置

查看方法1

SQL


以下内容将把没有根节点的平面XML转换为经典的EAV列表:

DECLARE @tbl TABLE(ID INT IDENTITY, YourXml XML);
INSERT INTO @tbl VALUES
 ('<tag1>1</tag1><tag2>2</tag2>')
,('<tag3>3</tag3><tag4>4</tag4><tag5>5</tag5>');

XQuery函数local name允许查询元数据,文本节点表示元素的内容

我也会使用一个长的表示法,比如:|ID | tag | value | 1 | tag1 | 1 | tag2 | 2 | tag2 | 8 | 2 | tag34 | 1 |您的答案与MSSQL本身非常相似,运行正常,但是否有更具伸缩性的方法?在我的例子中,我甚至没有预先准备好所有的标签名,即使我有,它的标签数也超过1000个。我知道如何生成和计算SQL字符串,但这似乎更像是一种黑客行为,而不是一种解决方案,尤其是在SQL中操作字符串。长表单表格的解决方案也足够了。请提供更多关于计划如何使用…>1000个标记的详细信息…?行是表单,标记是字段。有超过30种不同类型的表单,它们的字段有时会重叠,但没有一种表单类型具有所有字段,因此,为了获得所有有效的字段名,如果要使用Xquery,我必须以某种手动方式手动解析未指定数量的记录。当然,这应该有规范,但我离数据源非常远,我不想在更新规范的情况下遗漏条目。那么@Shnugo将数据作为键/值对检索的想法呢?我的朋友,你是一个向导,这尤其棒,因为我使用的是这种格式的数据anyway@LiudvikasAkelis,很高兴听到建议的解决方案对您有效。
| ID | tag   | value | 
| 1  | tag1  | 1     |
| 1  | tag2  | 2     |
| 2  | tag2  | 8     |
| 2  | tag34 | 1     |
-- DDL and sample data population, start
DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, xmldata XML);
INSERT INTO @tbl (xmldata) VALUES
(N'<tag1>1</tag1><tag2>2</tag2>')
,(N'<tag2>8</tag2><tag34>1</tag34>');
-- DDL and sample data population, end

-- Shred XML and convert it into a rectangular format
SELECT ID
    , col.value('(tag1/text())[1]','VARCHAR(10)') AS tag1 
    , col.value('(tag2/text())[1]','VARCHAR(10)') AS tag2
    , col.value('(tag3/text())[1]','VARCHAR(10)') AS tag3
    , col.value('(tag34/text())[1]','VARCHAR(10)') AS tag34
FROM @tbl AS tbl
    CROSS APPLY tbl.xmldata.nodes('.') AS tab(col);
+----+------+------+------+-------+
| ID | tag1 | tag2 | tag3 | tag34 |
+----+------+------+------+-------+
|  1 | 1    |    2 | NULL | NULL  |
|  2 | NULL |    8 | NULL | 1     |
+----+------+------+------+-------+
DECLARE @tbl TABLE(ID INT IDENTITY, YourXml XML);
INSERT INTO @tbl VALUES
 ('<tag1>1</tag1><tag2>2</tag2>')
,('<tag3>3</tag3><tag4>4</tag4><tag5>5</tag5>');
SELECT t.ID
      ,AllNodes.value('local-name(.)','nvarchar(max)') AS TagName
      ,AllNodes.value('text()[1]','nvarchar(max)') AS TagValue
FROM @tbl t
CROSS APPLY t.YourXml.nodes('/*') A(AllNodes);