MySQL XML查询

bfnvny8b  于 2023-01-01  发布在  Mysql
关注(0)|答案(4)|浏览(127)

我有点有问题的提取值函数在MySQL中。
下面是我的示例XML:

<As>
    <A>
        <B>Chan</B>
    </A>
    <A>
        <B>Shey</B>
    </A>
    <A>
        <B>Bob</B>
    </A>
</As>

下面是我当前的查询:

SELECT ExtractValue(@XML, '/As/A/B')

结果如下:

CHAN SHEY BOB

这是我想要的

CHAN
SHEY
BOB

有没有人能帮我实现这一点...谢谢。

xiozqbni

xiozqbni1#

这个问题在这里得到了解答:
Parse an XML string in MySQL
如果您将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
dgtucam1

dgtucam12#

您的问题的解决方案需要使用numbers表:整数表,1,2,3,......直到某个合理的值,比如1024。
然后,您将使用String Walking来解决该问题。
下面是numbers表的CREATE TABLE语句:

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;

上述内容使用值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)

我们使用ExtractValue(@XML, 'count(/As/A/B)')得到值3--匹配的XML元素的数量。
遍历数字1、2、3,我们从文本CHAN SHEY BOB中提取标记#1、标记#2、标记#3,并按空格进行拆分。
注:

  • ExtractXML返回的值是以空格分隔的。但是如果返回的文本中有空格-就不行了。它将与分隔空格无法区分。
  • 可以避免创建数字表和generate the numbers on the fly。我建议不要这样做--这将产生大量开销。拥有1024行的数字表总是很好的。

祝你好运!

mjqavswn

mjqavswn3#

DROP PROCEDURE IF EXISTS `test223`$$ CALL test223()

DELIMITER $$

CREATE DEFINER=`root`@`localhost` PROCEDURE `test223`()
BEGIN
  DECLARE xmlDoc TEXT;
  DECLARE i INT ;
  DECLARE coun INT;
  DECLARE child1 VARCHAR(400);
  DECLARE child2 VARCHAR(400);

  SET i =1;

  SET xmlDoc = '<Data><parent><child1>Example 1</child1><child2>Example 2</child2></parent><parent><child1>Example 3</child1><child2>Example 5</child2></parent><parent><child1>Example 5</child1><child2>Example 6</child2></parent></Data>';

  SET coun = ExtractValue(xmlDoc, 'count(/Data/parent/child1)');

  DROP TEMPORARY TABLE  IF EXISTS `parent`; 
  CREATE TEMPORARY TABLE parent (     child1 VARCHAR(400),   
    child2 VARCHAR(400) ); 

  WHILE i <= coun DO

    INSERT INTO parent
    SELECT ExtractValue(xmlDoc, '//parent[$i]/child1'), ExtractValue(xmlDoc,   '//parent[$i]/child2');

    SET i = i+1;

  END WHILE;

  SELECT * FROM  parent; 

END$$

DELIMITER ;

响应表:

+-----------------------+
| Child1    | Child2    |
|-----------|-----------|
|Example 1  | Example 2 |
|-----------|-----------|
|Example 3  | Example 5 |
|-----------|-----------|
|Example 5  | Example 6 |
|-----------|-----------|

来源http://pinaki-mukherjee.blogspot.in/2014/07/mysql-xml-querying.html

56lgkhnf

56lgkhnf4#

您可能需要重新考虑数据库设计。关系数据库系统的构建并不支持一个字段中的多个值。ExtractValue是一个过滤器,用于从字段中的XML数据中获取 * 一个 * 值,而不是获取多行数据。
你应该仔细阅读数据库规范化。所有的表都应该至少遵守第一范式(1NF),也就是说,每个字段只有一个值。不满足1NF的表通常很难查询,因为一般的SQL,特别是像MySQL这样的实现,没有给你提供任何好的查询工具。
如果您仍然想沿着非1NF表,我认为您可能需要从数据库中提取数据,然后在应用程序代码中执行这些工作。

相关问题