Попытка хранения XML-содержимого в SQL Server 2005 завершается с ошибкой (проблема с кодировкой)

Люди,

У меня есть веб-сервис, который возвращает данные в кодировке ISO-8859-1 - поскольку это не мое, я не могу изменить это: - (

Для целей аудита я хотел бы сохранить полученный XML из этих вызовов в таблицу SQL Server 2005, в которой у меня есть поле типа "XML NULL".

Из моего кода на С# я пытаюсь сохранить этот XML-контент в поле XML с помощью параметризованного запроса, что-то вроде

SqlCommand _cmd = new SqlCommand("INSERT INTO dbo.AuditTable(XmlField) VALUES(@XmlContents)", _connection);

_cmd.Parameters.Add("@XmlContents", SqlDbType.Xml);
_cmd.Parameters["@XmlContents"].Value = (my XML response);

_cmd.ExecuteNonQuery();

Неисправность - когда я запускаю этот код, я возвращаю сообщение об ошибке:

Msg 9402, уровень 16, состояние 1, строка 1
Разбор XML: строка 1, символ xy, неспособность переключить кодировку

?? Я пытался выяснить, где и как я могу "переключить" кодировку - пока не повезло. Что это на самом деле значит? Я не могу хранить XML с кодировкой ISO-8859-1 в SQL Server 2005?? Или есть трюк: a) сообщить SQL Server 2005 просто принять эту кодировку или b) автоматически преобразовать ответ webservice в кодировку UTF перед сохранением в SQL Server?

Спасибо за любые подсказки, указатели, подсказки! Марк

Ответ 1

Вам нужно преобразовать в utf-16

Я не эксперт по XML на SQL Server, хотя я его использую, но в прошлом году у нас была такая же проблема, и это было неправильное соответствие строкового типа данных, объявленного в SQL, по сравнению с отправляемым xml.

Ответ 3

Не могли бы вы переписать xml как unicode (возможно, в MemoryStream) и отправить это? Примечание. Если вы просто сохраняете данные, вы можете использовать varbinary(max) (и это будет быстрее). Это не имеет проблем с кодированием, а также позволит вам проверять любой поврежденный xml, который вы получаете.

Если вы запрашиваете данные как xml внутри сервера базы данных, то xml, очевидно, способ пойти.

Ответ 5

Изменить
Я пропустил часть вопроса ISO-8859-1. Решение ниже хорошо для UTF8, но, очевидно, не решает проблему Marc, поскольку он не может изменить кодировку.


Здесь решение, которое я использую:

И немного измененная версия кода сверху (я протестировал его с файлом UTF8 с помощью SQL 2005):

using System.IO;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;

...
using (SqlConnection connection = new SqlConnection("conn string"))
{
    connection.Open();
    string sql = "INSERT INTO mytable (xmlColumn) VALUES (@xmlData)";
    using (SqlCommand command = new SqlCommand(sql, connection))
    {
        // Swap round if the source file is unicode         
        string xml = File.ReadAllText(@"C:\myxml.xml");
        //string xml = File.ReadAllText(@"C:\myxml.xml", Encoding.Unicode);

        using (MemoryStream stream = new MemoryStream())
        {
            using (StreamWriter writer = new StreamWriter(stream, Encoding.Unicode))
            {
                writer.Write(xml);
                writer.Flush();
                stream.Position = 0;

                SqlParameter parameter = new SqlParameter("@xmlData", SqlDbType.Text);
                parameter.Value = new SqlXml(stream);
                command.Parameters.Add(parameter);
                command.ExecuteNonQuery();
            }
        }
    }
}

Ответ 6

Даже я столкнулся с подобной проблемой при вставке xml-контента в db. Например, вход был таким:

Insert Into TestData(Xml) Values ('<?xml version="1.0" encoding="UTF-8"?><Test/>')

Этот тип инструкции использовался для отказа, и я получал ошибку "неспособность переключиться..". Позже я просто префикс N в строку xml следующим образом:

Insert Into TestData(Xml) Values (N'<?xml version="1.0" encoding="UTF-8"?><Test/>')

После этого он начал работать!!!