MySQL XML 查询

She*_*ego 5 mysql sql

我在使用 MySQL 中的 ExtractValue 函数时遇到了一些问题。

这是我的 XML 示例:

<As>
    <A>
        <B>Chan</B>
    </A>
    <A>
        <B>Shey</B>
    </A>
    <A>
        <B>Bob</B>
    </A>
</As>
Run Code Online (Sandbox Code Playgroud)

这是我当前的查询:

SELECT ExtractValue(@XML, '/As/A/B')
Run Code Online (Sandbox Code Playgroud)

结果如下:

CHAN SHEY BOB
Run Code Online (Sandbox Code Playgroud)

这就是我想要的:

CHAN
SHEY
BOB
Run Code Online (Sandbox Code Playgroud)

有人可以帮我实现这个目标吗?谢谢。

Shl*_*ach 5

解决你的问题需要使用一个numbers表:一个整数表,1,2,3,.... 直到某个合理的值,比如 1024。

然后,您可以使用字符串遍历来解决该问题。

以下是该表的 CREATE TABLE 语句numbers

CREATE TABLE numbers (
  `n` smallint unsigned NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`n`)
)
;
INSERT INTO numbers VALUES (NULL);
INSERT INTO numbers SELECT NULL FROM numbers;
INSERT INTO numbers SELECT NULL FROM numbers;
INSERT INTO numbers SELECT NULL FROM numbers;
INSERT INTO numbers SELECT NULL FROM numbers;
INSERT INTO numbers SELECT NULL FROM numbers;
INSERT INTO numbers SELECT NULL FROM numbers;
INSERT INTO numbers SELECT NULL FROM numbers;
INSERT INTO numbers SELECT NULL FROM numbers;
INSERT INTO numbers SELECT NULL FROM numbers;
INSERT INTO numbers SELECT NULL FROM numbers;
Run Code Online (Sandbox Code Playgroud)

上面填充值 1..1024

现在查询:

SELECT 
  SUBSTRING_INDEX(SUBSTRING_INDEX(ExtractValue(@XML, '/As/A/B'), ' ', n), ' ', -1) AS value
FROM
  numbers
WHERE
  n BETWEEN 1 AND ExtractValue(@XML, 'count(/As/A/B)')
;


+-------+
| value |
+-------+
| Chan  |
| Shey  |
| Bob   |
+-------+
3 rows in set (0.02 sec)
Run Code Online (Sandbox Code Playgroud)

我们用来ExtractValue(@XML, 'count(/As/A/B)')获取值3——匹配的 XML 元素的数量。

遍历数字 1、2、3,我们从文本中提取标记 #1、标记 #2、标记 #3 CHAN SHEY BOB,并按空格分割。

笔记:

  • ExtractXML 返回以空格分隔的值。但如果返回的文本中有空格 - 则不行。它与分隔空间没有区别。

  • 可以避免创建数字表并动态生成数字。我建议不要这样做——这会产生大量开销。拥有 1024 行号表总是好的。

祝你好运!


Sha*_*awn 4

这个问题在这里得到了解答:

在 MySQL 中解析 XML 字符串

如果您将 child 更改为“B”,该文章中的解决方案应该有效:

DECLARE i INT DEFAULT 1;
DECLARE count DEFAULT ExtractValue(xml, 'count(//child)');

WHILE i <= count DO
SELECT ExtractValue(xml, '//child[$i]');
SET i = i+1;
END WHILE
Run Code Online (Sandbox Code Playgroud)