.NET:如何将XML文档插入SQL Server

Ian*_*oyd 10 xml sql-server ado.net xml-serialization sql-server-2008

我想将任意XML插入SQL Server.XML包含在一个XmlDocument对象中.

我要插入的列要么nvarchar,ntext或xml列(如果它使你的生活更轻松,那么你可以选择哪个类型,它真的是一个xml列.)

原型

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

}
Run Code Online (Sandbox Code Playgroud)

我问的原因是因为我试图找到正确的方法来转换XmlDocument成数据库可以采取的东西 - 确保编码正确:

  • 我必须确保在插入期间使用的编码与数据库采用的匹配
  • 我必须同步<?xml version="1.0" encoding="windows-1252"?>元素

我知道ntext,nvarchar或者xml存储UTF-16在SQL Server内部.所以我必须确保将数据作为UTF-16提供给SQL Server.这对于String.NET中的s 来说不是问题,因为它们是 unicode UTF-16.

第二个问题,即同步编码属性,是一个难以破解的难题.我必须弄清楚如何通过XmlDocument对象找到声明元素:

<?xml version="1.0" encoding="windows-1252"?>   (or whatever the encoding may be)
Run Code Online (Sandbox Code Playgroud)

并将其调整为UTF-16

<?xml version="1.0" encoding="UTF-16"?>
Run Code Online (Sandbox Code Playgroud)

我天真的尝试(失败)

忽略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;
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

这失败是因为sql我尝试运行的是:

INSERT INTO LiveData (RawXML) 
VALUES ('System.Xml.XmlDocument')
Run Code Online (Sandbox Code Playgroud)

这是因为XmlDocument.ToString()返回" System.Xml.XmlDocument".偷看实现,它看到它实际上是在调用:

this.GetType().ToString();
Run Code Online (Sandbox Code Playgroud)

旁白:微软似乎已经不遗余力地阻止你将Xml作为一个字符串 - 大概是因为它导致了错误(但他们没有告诉我们什么错误,为什么他们是错误,或者正确的方法将一个XmlDocument转换为 String!)

也可以看看

Bit*_*KFu 9

您必须使用SqlParameter.我建议这样做:

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

SQL应如下所示:

String sql = "INSERT INTO "+tableName+" ("+columnName+") VALUES (@xml)";
Run Code Online (Sandbox Code Playgroud)

由于第一个子节点始终是xml节点,因此可以使用以下语句替换编码.

xmlToSave.FirstChild.InnerText = "version=\"1.0\" encoding=\"UTF-16\"";
Run Code Online (Sandbox Code Playgroud)

总而言之,它看起来像这样:

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;
      }
   }
}
Run Code Online (Sandbox Code Playgroud)