Попытка хранения 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.
Ответ 2
Я нашел это в google. http://social.msdn.microsoft.com/forums/en-US/sqlxml/thread/d40ef582-4ffe-4f4b-b6b8-03c6c0ba1a32/
Я думаю, вы можете заменить строку
_cmd.Parameters.Add("@XmlContents", SqlDbType.Xml);
с
_cmd.Parameters.Add("@XmlContents", System.Data.SqlTypes.SqlXml);
Ответ 3
Не могли бы вы переписать xml как unicode (возможно, в MemoryStream
) и отправить это? Примечание. Если вы просто сохраняете данные, вы можете использовать varbinary(max)
(и это будет быстрее). Это не имеет проблем с кодированием, а также позволит вам проверять любой поврежденный xml, который вы получаете.
Если вы запрашиваете данные как xml внутри сервера базы данных, то xml
, очевидно, способ пойти.
Ответ 4
Я разместил некоторую информацию:
http://mrboratech.blogspot.com/2009/02/how-to-store-xmldocument-mssql-2005-as.html
Ответ 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/>')
После этого он начал работать!!!