.NET: Как вставить XML-документ в SQL Server

Я хочу вставить произвольный XML в SQL Server. XML содержится в XmlDocument .

Столбец, в который я хочу вставить, - это столбец nvarchar , ntext или xml . можете выбрать, какой это тип. На самом деле это столбец xml .)

Прототип

void SaveXmlToDatabase(DbConnection connection,
      XmlDocument xmlToSave,
      String tableName, String columnName);
{

}

Причина, по которой я спрашиваю, заключается в том, что я пытаюсь найти правильный способ превратить XmlDocument во что-то, что может принять база данных, - соблюдая правильные кодировки:

  • Я должен убедиться, что кодировка, используемая во время вставки, соответствует тому, что принимает база данных
  • Мне нужно синхронизировать элемент

Я знаю, что ntext , nvarchar или xml хранятся как UTF-16 внутри SQL Server. Поэтому я должен обязательно передать данные в SQL Server как UTF-16. Это не проблема для String в .NET, поскольку они являются unicode UTF-16.

Вторая проблема, синхронизация атрибута кодирования, - более крепкий орешек. Мне нужно выяснить, как найти элемент объявления через объект XmlDocument :

<?xml version="1.0" encoding="windows-1252"?>   (or whatever the encoding may be)

и настроить его на UTF-16

<?xml version="1.0" encoding="UTF-16"?>

Моя наивная попытка (которая не удалась)

Игнорирование кодировки в Объявление XML и просто выяснение того, как сохранить что-либо в SQL Server:

void SaveXmlToDatabase(DbConnection connection,
      XmlDocument xmlToSave,
      String tableName, String columnName);
{
   String sql = "INSERT INTO "+tableName+" ("+columnName+") 
          VALUES ('"+xmlToSave.ToString()+"')";

   using (DbCommand command = connection.CreateCommand())
   {
      command.CommandText = sql;

      DbTransaction trans = connection.BeginTransaction();
      try
      {
         command.ExecuteNonQuery();
         trans.Commit();
      }
      catch (Exception)
      {
         trans.Rollback();
         throw;
      }
   }
}

Это не удается, потому что sql , который я пытаюсь запустить, выглядит следующим образом:

INSERT INTO LiveData (RawXML) 
VALUES ('System.Xml.XmlDocument')

Это потому, что XmlDocument.ToString () возвращает « System.Xml.XmlDocument ».Посмотрев на реализацию, можно увидеть, что она буквально вызывает:

this.GetType().ToString();

В сторону: Microsoft, похоже, изо всех сил старалась помешать вам получить Xml в виде строки - {{1} } предположительно потому, что это приводит к ошибкам (но они не говорят нам, какие ошибки, почему это ошибки, или правильный способ преобразовать XmlDocument в String !)

См. также

10
задан Shaggy 27 September 2019 в 10:38
поделиться

1 ответ

Вы должны использовать SqlParameter. Я бы порекомендовал сделать это следующим образом:

command.Parameters.Add(
   new SqlParameter("@xml", SqlDbType.Xml) 
       {Value = new SqlXml(new XmlTextReader(xmlToSave.InnerXml
                       , XmlNodeType.Document, null)) })

и SQL должен выглядеть так:

String sql = "INSERT INTO "+tableName+" ("+columnName+") VALUES (@xml)";

И поскольку первым дочерним элементом всегда является узел xml, вы можете заменить кодировку следующим оператором.

xmlToSave.FirstChild.InnerText = "version=\"1.0\" encoding=\"UTF-16\"";

В целом это будет выглядеть так:

void SaveXmlToDatabase(DbConnection connection,
      XmlDocument xmlToSave,
      String tableName, String columnName);
{
   String sql = "INSERT INTO "+tableName+" ("+columnName+") VALUES (@xml)";

   using (DbCommand command = connection.CreateCommand())
   {
      xmlToSave.FirstChild.InnerText = "version=\"1.0\" encoding=\"UTF-16\"";             
      command.CommandText = sql;
      command.Parameters.Add(
        new SqlParameter("@xml", SqlDbType.Xml) 
           {Value = new SqlXml(new XmlTextReader(xmlToSave.InnerXml
                       , XmlNodeType.Document, null)) });


      DbTransaction trans = connection.BeginTransaction();
      try
      {
         command.ExecuteNonQuery();
         trans.Commit();
      }
      catch (Exception)
      {
         trans.Rollback();
         throw;
      }
   }
}
9
ответ дан 4 December 2019 в 00:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: