4

我在 MySQL 中遇到了 ExtractValue 函数的问题。

这是我的示例 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

有人可以帮我实现这一目标..谢谢。

4

4 回答 4

4

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

在 MySQL 中解析 XML 字符串

如果您将孩子更改为“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
于 2012-07-11T20:32:07.200 回答
4

解决您的问题需要使用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;

以上填充值 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)

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

遍历数字 1、2、3,我们从 textCHAN SHEY BOB中提取 token #1、token #2、token #3,并按空格分割。

笔记:

  • ExtractXML 返回以空格分隔的值。但是,如果返回的文本中有空格 - 不行。它与分隔空间无法区分。

  • 可以避免创建数字表并即时生成数字。我建议不要——它会产生很多开销。拥有一个 1024 行数字表总是很不错的。

祝你好运!

于 2012-07-09T10:31:27.920 回答
0
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 ;

Response Table :

+---------------------+
| 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

于 2014-07-26T10:26:59.493 回答
-1

您可能需要重新考虑您的数据库设计。关系数据库系统不是为了支持一个字段中的多个值而构建的。ExtractValue是一种过滤器,用于从字段中的 XML 数据中提取一个值,而不是用于获取多行数据。

您应该阅读数据库规范化。所有表格至少应遵守第一范式(1NF),即每个字段中只有一个值。不满足 1NF 的表通常很难查询,因为一般的 SQL 和特别是 MySQL 等实现并没有为您提供任何用于此类查询的好工具。

如果您仍然想与非 1NF 表一起努力,我认为您可能需要从数据库中获取数据并在应用程序代码中完成工作。

于 2012-07-01T11:16:31.920 回答