【问题标题】:How to select all children from XML in Sql Server?如何从 Sql Server 中的 XML 中选择所有子项?
【发布时间】:2021-07-11 10:46:43
【问题描述】:

当我运行它只考虑第一个值的选择查询时,我有以下 XML,我在这里缺少什么?

<?xml version="1.0" encoding="utf-16"?>
<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <string>1</string>
  <string>2</string>
  <string>3</string>
  .............
</ArrayOfString>

下面的查询只返回 1,我希望它返回所有值,如 1,2,3...

SELECT xmlu.v1.value('string[1]', 'BIGINT')
                                    FROM
           @xml.nodes('/ArrayOfString')
           AS xmlU(v1)

【问题讨论】:

  • "只考虑第一个值" 因为那是你要求的:'string[1]'; [1] 表示第一个节点。您是说要分隔结果吗?
  • @Larnu,不,我只想要多行。实际上我想在 where 子句中使用结果。像这样where id in (SELECT xmlu.v1.value('string[1]', 'BIGINT') FROM @xml.nodes('/ArrayOfString') AS xmlU(v1))

标签: sql-server xml


【解决方案1】:

如果您希望每个 string 节点有一行,则需要在您的 nodes 子句中包含 string 节点:

SELECT AOS.s.value('(./text())[1]','bigint') AS string --If it's string, why are you asking for a bigint?
FROM (VALUES(@XML))V(X)
     CROSS APPLY V.X.nodes('/ArrayOfString/string')AOS(s);

【讨论】:

  • 这样使用可以吗?我的意思是性能方面。可以有 100 个字符串子节点
  • 我可以完全控制从代码创建 XML 变量并传递给存储过程。所以请指教,这是传递 XML 的正确方法吗?还是我需要更改 XML 架构?所以我唯一的目的是将多个值传递给存储过程。
  • "这样用可以吗?" 为什么不"ok"; 100 行对于 RDBMS 来说根本不算什么。
  • “所以我唯一的目的是将多个值传递给存储过程” 为什么不使用表类型参数 @viveknuna ,如果那是您的 true 目标?
  • 我建议表类型参数比xml 更好,但是,这是一个完全不同的问题。如果您想询问使用 TTP 而不是 XML 的好处,您应该提出一个新问题,@viveknuna。
【解决方案2】:

您似乎正在寻找类似以下的内容。

最好不要使用IN 子句,因为它通常会被转换为低效的OR 表达式。

SQL

-- DDL and sample data population, start
DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, city VARCHAR(20));
INSERT INTO @tbl (city) VALUES
('Miami'),
('Orlando'),
('Dallas'),
('New York'),
('Hollywood');

DECLARE @parameter XML =
N'<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <string>1</string>
    <string>2</string>
    <string>3</string>
</ArrayOfString>'
-- DDL and sample data population, end

;WITH rs AS
(
    SELECT c.value('.', 'INT') AS ID
    FROM @parameter.nodes('/ArrayOfString/string/text()') AS t(c)
)
SELECT * 
FROM @tbl AS t INNER JOIN 
     rs ON t.ID = rs.ID;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多