Простой ответ заключается в том, что ошибка говорит вам о проблеме. Но объясню дальше. Возьмите это простое утверждение:
DECLARE @xml varchar(MAX);
SET @XML = '
<root>
<child>
<element attribute="1">value</element>
<element attribute="2" attribute="2">Another Value</element>
</child>
</root>';
SELECT *
FROM (VALUES(CONVERT(xml, @XML)))V(X);
Если вы запустите это, вы получите ошибку:
Сообщение 9437, уровень 16, состояние 1, строка 11 Синтаксический анализ XML: строка 5, символ 46, повторяющийся атрибут
Не удивительно, как если бы вы смотрели, второй element
узел имеет attribute
, объявленный дважды.
<ч />
Итак, как это исправить?
Во-первых, это означает, что вы храните свои XML-данные как тип данных, отличный от типа данных xml
. XML должен храниться с использованием типа данных xml
(это именно то, для чего он предназначен), и в нем может храниться только действительный XML; в результате вы не смогли бы вставить неверный XML в строку и не оказались бы в этой позиции. Как и вы, есть только одна вещь, которую вы можете сделать; найти все «плохие» строки:
SELECT tank_inspection
FROM bulk_site_tank
WHERE TRY_CONVERT(xml,tank_inspection) IS NULL
AND tank_inspection IS NOT NULL;
Затем проверьте каждую строку, возвращенную в указанном выше наборе данных, и исправьте данные. Сделайте это действительным XML. После этого исправьте ваш тип данных:
ALTER TABLE bulk_site_tank ALTER COLUMN tank_inspection xml;
Теперь все в формате XML, вы можете исправить свой запрос:
SELECT ship_to_cust_num,
tank_num,
tank_capacity_qty,
tank_pkg_type_code,
REPLACE(b.tank_inspection.value('(/TankInspection/Questions/Question[@AASAQno="9"]/@QAns)[1]', 'varchar(50)'), '#', '') --AS ?
FROM bulk_site_tank b
WHERE b.tank_inspection IS NOT NULL;
Заметьте, я изменил синтаксис ANSI_NULL
и избавился от NOLOCK
(так как я предполагаю, что вы не знаете, что он на самом деле здесь делает). Выражения CAST
/ CONVERT
тоже пропали, и я удалил COALESCE
. Поскольку ваше выражение value
возвращает varchar(50)
, а COALESCE
имеет 0
для второго параметра. Это неявно приведёт значение, возвращённое из XML, к int
и, вероятно, приведет к ошибке преобразования.
Боюсь, что вы должны очистить свои данные, но никто больше не может вам здесь помочь, я боюсь. Это только одна из причин, по которой неправильный выбор типов данных является проблемой; как если бы использовался правильный тип данных, то, как я уже говорил, неверный XML никогда не мог быть вставлен.
Удачи!