Intereting Posts
динамическое переключение имени таблицы и столбца с использованием переменных связывания Добавьте столбец в таблицу со значением по умолчанию, равным значению существующего столбца Безопасность веб-баз данных HTML5 Запрос доктрины – игнорирование пробелов Как создать временной ряд в Access и использовать его в запросе Как указать имя поля в таблице в Access с использованием SQL Postgres получают первую и последнюю версию для отдельного поставщика Выполнение команды COPY в удаленной базе данных с использованием локального файла Наиболее эффективный способ запроса нескольких идентичных таблиц в отдельных базах данных SQL для переноса пар строк в столбцы в базе данных MS ACCESS Ресурсы превышены во время выполнения запроса Могу ли я запустить H2 для автоматической сборки схемы в базе данных в памяти? SQL Oracle – отображение значений только один раз за столбец Почему этот простой запрос SQL не работает в MS Access? Почему вы не можете смешивать значения Aggregate и Non-Aggregate в одном SELECT?

MySQL XML Querying

У меня проблемы с функцией ExtractValue в 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 

Может кто-то, пожалуйста, помогите мне достичь этого .. спасибо.

На эту проблему ответили:

Разбор XML-строки в MySQL

Решение из этой статьи должно работать, если вы меняете ребенка на «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 

Решение вашей проблемы потребует использования таблицы numbers : таблицы целых чисел, 1,2,3, … до некоторого разумного значения, скажем 1024.

Затем вы можете использовать String Walking для решения проблемы.

Вот оператор 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) 

Мы используем ExtractValue(@XML, 'count(/As/A/B)') чтобы получить значение 3 – количество соответствующих XML-элементов.

Пройдя по номерам 1, 2, 3, мы извлекаем токен # 1, токен # 2, токен № 3 из текста CHAN SHEY BOB , разделяя пробел.

Заметки:

  • ExtractXML возвращает пространство значений с разделителями. Но если в возвращенном тексте есть пробел – нет. Это было бы неотличимо от разделительных пространств.

  • Можно избежать создания таблицы чисел и генерировать числа «на лету» . Я советую – это создало бы много накладных расходов. Всегда иметь таблицу номеров строк в 1024 строк.

Удачи!

 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

Возможно, вам придется переосмыслить дизайн своей базы данных. Реляционные системы баз данных не построены для поддержки нескольких значений в одном поле. ExtractValue понимается как фильтр для извлечения одного значения из данных XML в поле, а не для получения нескольких строк данных.

Вы должны прочитать о нормализации базы данных. Все таблицы должны, по крайней мере, придерживаться первой нормальной формы (1NF), т. Е. Только одно значение в каждом поле. Таблицы, которые не удовлетворяют 1NF, обычно довольно сложно запросить, поскольку SQL в целом и реализации, такие как MySQL, в частности, не дают вам никаких хороших инструментов для такого запроса.

Если вы все еще хотите бороться вместе со своей таблицей, отличной от 1NF, я думаю, вам может понадобиться извлечь ваши данные из базы данных и выполнить работу в вашем коде приложения.