C# SqlBulkCopy错误:无效字符,但XML字符串似乎有效

C# SqlBulkCopy错误:无效字符,但XML字符串似乎有效,c#,sql,xml,escaping,sqlbulkcopy,C#,Sql,Xml,Escaping,Sqlbulkcopy,我对SqlBulkCopy(在c#,framework 4.5.1中)有一个问题,其中一个有效的XML字符串导致错误System.Data.SqlClient.SqlException:{“XML解析:第1行,字符29,需要字符串文本”}” 桌子是 CREATE TABLE [dbo].[JobManager_BigTextTest]( [PKID] [int] IDENTITY(1,1) NOT NULL, [BigXML] [xml] NOT NULL, PK_JobManager_BigT

我对SqlBulkCopy(在c#,framework 4.5.1中)有一个问题,其中一个有效的XML字符串导致错误System.Data.SqlClient.SqlException:{“XML解析:第1行,字符29,需要字符串文本”}”

桌子是

CREATE TABLE [dbo].[JobManager_BigTextTest](
[PKID] [int] IDENTITY(1,1) NOT NULL,
[BigXML] [xml] NOT NULL, PK_JobManager_BigTextTest] PRIMARY KEY CLUSTERED 
(
    [PKID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [Data]
) ON [Data] TEXTIMAGE_ON [Data]
XML的SQL插入(工作正常)是

将一行(或多行)添加到数据表后,执行大容量复制的c#方法被称为

public static void BulkCopyProcessChunk
(
    string tableName,
    DataTable dataTable,
    SqlConnection connection,
    SqlTransaction transaction
)
{
    using (var sbc = new SqlBulkCopy(connection, SqlBulkCopyOptions.Default, transaction))
    {
        sbc.BulkCopyTimeout = 0; // Indefinite time out
        sbc.DestinationTableName = tableName;

        sbc.BatchSize = dataTable.Rows.Count;

        foreach (DataColumn r in dataTable.Columns)
        {
            sbc.ColumnMappings.Add(r.ColumnName, r.ColumnName);
        }

        sbc.WriteToServer(dataTable); // <--- error occurs here
    }
}
公共静态无效BulkCopyProcessChunk
(
字符串表名,
数据表数据表,
SqlConnection连接,
SqlTransaction事务
)
{
使用(var sbc=newsqlbulkcopy(连接,SqlBulkCopyOptions.Default,事务))
{
sbc.BulkCopyTimeout=0;//无限期超时
sbc.DestinationTableName=表名;
sbc.BatchSize=dataTable.Rows.Count;
foreach(dataTable.Columns中的DataColumn r)
{
sbc.ColumnMappings.Add(r.ColumnName,r.ColumnName);
}

sbc.WriteToServer(dataTable);//错误消息指向第1行,字符29

此时,默认名称空间属性需要一个字符串文本…您正在以双qoutes格式提供名称空间。因此,一切似乎都正常,但:

有几篇文章()指出了与
SqlBulkCopy
和双qoutes有关的问题

您可以尝试以下操作:


  • 使用单qoutes而不是双qoutes:

    最好的做法是在SQLServerManagementStudio(SSMS)中运行查询SQL Server附带的。错误消息比c#中的要好100倍。c#a-1中的表通常会出现,因为表未构造,或者表中没有列。请确保您没有从class.form构造函数调用代码。在类构造后,它应该在form load方法中。我运行了query,如上所述,在同一个表中插入完全相同的字符串,并且该表或字符串似乎没有任何问题。我尝试使用单引号,但成功了。感谢您的帮助!!!!
    public static DataTable GetDataTableFromSqlDestination(string tableName)
    {
        tableName = MakeInjectionProof(tableName); // error if injection discovered
        var dataTable = new DataTable();
        var query = $"SELECT * FROM [{tableName}] WHERE 1 = 0";
    
        using (var connection = new SqlConnection("my_connection"))
        using (var command = new SqlCommand(query, connection))
        {
            command.CommandTimeout = connection.ConnectionTimeout;
            command.CommandType = CommandType.Text;
            connection.Open();
    
            var da = new SqlDataAdapter(command);
    
            da.FillSchema(dataTable, SchemaType.Mapped);
    
            connection.Close();
    
            dataTable.PrimaryKey = null; // strip off primary key
            dataTable.Columns.Remove("PKID");
        }
    
        return dataTable;
    }
    
    public static void BulkCopyProcessChunk
    (
        string tableName,
        DataTable dataTable,
        SqlConnection connection,
        SqlTransaction transaction
    )
    {
        using (var sbc = new SqlBulkCopy(connection, SqlBulkCopyOptions.Default, transaction))
        {
            sbc.BulkCopyTimeout = 0; // Indefinite time out
            sbc.DestinationTableName = tableName;
    
            sbc.BatchSize = dataTable.Rows.Count;
    
            foreach (DataColumn r in dataTable.Columns)
            {
                sbc.ColumnMappings.Add(r.ColumnName, r.ColumnName);
            }
    
            sbc.WriteToServer(dataTable); // <--- error occurs here
        }
    }