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

問題を解決するには、テーブルを使用する必要がありnumbersます。整数のテーブル、1、2、3、....最大値(1024など)まで。

次に、 StringWalkingを使用して問題を解決します。

テーブルのCREATETABLEステートメントは次の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)

ExtractValue(@XML, 'count(/As/A/B)')3-一致するXML要素の数を取得するために使用します。

番号1、2、3を実行して、テキストからトークン#1、トークン#2、トークン#3を抽出CHAN SHEY BOBし、スペースで分割します。

ノート:

  • ExtractXMLは、スペースで区切られた値を返します。ただし、返されたテキスト内にスペースがある場合は、問題ありません。区切りスペースと見分けがつかないでしょう。

  • 数値テーブルの作成を回避し、その場で数値を生成することができます。私は反対することをお勧めします-それは多くのオーバーヘッドを生み出すでしょう。1024行番号のテーブルがあると、いつでも便利です。

幸運を!

于 2012-07-09T10:31:27.920 に答える
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 に答える
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 ;

応答表:

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

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

于 2014-07-26T10:26:59.493 に答える
-1

データベースの設計を再考する必要があるかもしれません。リレーショナルデータベースシステムは、1つのフィールドで複数の値をサポートするようには構築されていません。ExtractValueは、複数行のデータを取得するためではなく、フィールド内のXMLデータから1つの値をフェッチするためのフィルターとして意図されています。

データベースの正規化についてよく読んでください。すべてのテーブルは、少なくとも最初の正規形(1NF)に準拠している必要があります。つまり、各フィールドに1つの値のみが準拠している必要があります。1NFを満たさないテーブルは、通常、SQL全般、特にMySQLなどの実装では、このようなクエリに適したツールが提供されないため、クエリを実行するのはかなり困難です。

それでも1NF以外のテーブルで苦労したい場合は、データベースからデータをフェッチして、アプリケーションコードで作業を行う必要があると思います。

于 2012-07-01T11:16:31.920 に答える