防止 SqlBulkCopy 更改 XML 值

Posted

技术标签:

【中文标题】防止 SqlBulkCopy 更改 XML 值【英文标题】:Prevent SqlBulkCopy to change XML value 【发布时间】:2021-10-23 13:45:17 【问题描述】:

我正在使用SqlBulkCopy 将数据从一个数据库传输到另一个数据库。我的问题是我的 XML 列将在批量复制期间更改。

我认为 SqlBulkCopy 类正在解析/计算 XML 并“简化” XML。

原值:

<Item></Item>

改变值:

<Item/>

这会导致我的验证过程出错,因为原始 XML 不是存储在目标数据库中的值。

有没有办法阻止SqlBulkCopy 类更改我的XML? 因为之前生成的SQL语句不知道有XML列,所以我也无法转换成nvarchar(max)

我的代码:

using (SqlDataAdapter adapter = new SqlDataAdapter(source_command))

    using (DataTable table = new DataTable())
    
        adapter.Fill(table);
        using (SqlConnection destination = new SqlConnection(destination_connectionstring))
        
            destination.Open();

            using (SqlBulkCopy bulkCopy = new SqlBulkCopy(destination, SqlBulkCopyOptions.KeepIdentity | SqlBulkCopyOptions.KeepNulls | SqlBulkCopyOptions.CheckConstraints, null))
            
                bulkCopy.DestinationTableName = destination_table;
                bulkCopy.BulkCopyTimeout = 1200;

                foreach (DataColumn column in table.Columns)
                
                    bulkCopy.ColumnMappings.Add(new SqlBulkCopyColumnMapping(column.ColumnName, column.ColumnName));
                

                try
                
                    bulkCopy.WriteToServer(table);
                
                catch (Exception ex)
                
                    Log.Logger.Error(ex.ToString());
                    throw;
                
                finally
                
                    table.Dispose();
                
            
        
    

xml-string 表示在源数据库和目标数据库中是相同的,这一点很重要。

【问题讨论】:

它仍然是有效的 XML,代表完全相同的数据,所以你应该改变你的验证来处理它 当然是,但是处理系统假定它是完全相同的符号。由于处理系统的限制,在这方面无法更改验证过程。不幸的是,我不能忽视这个要求 Unfortunately, I cannot ignore this requirement. 不幸的是,SqlBulkCopyOptions 没有 CaterForPoorlyWrittenProcessingSystemsThatTreatXmlAsText 标志。如果您“不能”更改验证过程,并且“不能”将列数据类型从 xml 更改为 nvarchar(max),则不能使用 SqlBulkCopy table中列的数据类型是什么,你是怎么传的?你也许可以通过XmlDocumentPreserveWhitespace = true 【参考方案1】:

问题与SqlBulkCopy类无关。

我通过在字符串表示不同的情况下添加特定验证来解决我的问题。如果是这样,我在 sql server 上运行一个 select 并转换为 XML。

例子:

SELECT
  CONVERT(XML, '<test><item></item></test>'

然后我得到这样的结果:

<test>
   <item/>
</test>

也可以命令 sql server 保留空格。 更多关于这个问题:https://dba.stackexchange.com/questions/223496/sql-server-changes-xml-structure-when-inserted

【讨论】:

以上是关于防止 SqlBulkCopy 更改 XML 值的主要内容,如果未能解决你的问题,请参考以下文章

防止有条件地选择输入值更改

防止提交路线更改 Formik AutoSave

防止 BeautifulSoup 将我的 XML 标记转换为小写

防止视图布局子视图

如何防止 sizeToFit 更改 UILabel 宽度?

C# 中的 SqlBulkCopy 类正在更改数值