Сбой Oracle extractValue, когда запрос возвращает много строк - PullRequest
3 голосов
/ 15 июня 2009

У меня, вероятно, незавидная задача - написать запрос переноса данных, чтобы заполнить существующие записи значением для нового столбца, добавляемого в таблицу производственной базы данных. Таблица имеет порядка 200 000 строк.

Источник значения находится в каком-то XML, который хранится в базе данных. У меня есть XPath, который извлекает нужное мне значение, и использование extractValue для получения значения кажется вполне приемлемым, пока число записей, обновляемых запросом, не станет больше, чем те, которые были в моей тестовой БД.

Как только набор записей увеличивается до некоторого случайного размера, где-то около 500 строк, я начинаю получать сообщение об ошибке «ORA-19025: EXTRACTVALUE возвращает значение только одного узла». Поняв, что в базе данных есть какая-то странная строка, для которой не было уникального результата для XPath, я попытался ограничить записи в запросе, чтобы изолировать неверную запись. Но как только я сократил набор записей, ошибка исчезла. На самом деле нет строки, которая бы возвращала более одного значения для этого запроса XPath. Похоже, что-то подозрительное происходит с extractValue.

Кто-нибудь знает что-нибудь об этом? Я не эксперт по SQL, и даже тогда провел больше времени на SQL Server, чем Oracle. Так что, если я не могу заставить это работать, я думаю, что мне осталось немного поиграться с курсорами или что-то в этом роде.

Любой совет / помощь? Если это поможет, мы запускаем 10g на сервере. Спасибо!

1 Ответ

5 голосов
/ 15 июня 2009

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

Например, используйте предикат XMLPath, который даст вам узел во второй позиции (в настоящее время у меня нет доступа к БД с объектами XML, поэтому я не могу гарантировать, что следующее синтаксически идеально):

  SELECT SourceKey
       , EXTRACTVALUE(SourceXML, '/foo/bar/baz[1]')
       , EXTRACTVALUE(SourceXML, '/foo/bar/baz[2]')
    FROM SourceTable
   WHERE EXTRACTVALUE(SourceXML, '/foo/bar/baz[2]') IS NOT NULL;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...