SqlBulkCopy получил исключение: «От клиента bcp для colid получена недопустимая длина столбца».C#

Место общения программистов C#
Ответить
Anonymous
 SqlBulkCopy получил исключение: «От клиента bcp для colid получена недопустимая длина столбца».

Сообщение Anonymous »

У меня есть код, использующий SqlBulkCopy для клонирования множества таблиц, раньше он работал, но очень странно, недавно получил исключение.

Получил неверную длину столбца от клиента bcp для colid

Я выполнил поиск по этому исключению, но до сих пор не решил проблему.

Код: Выделить всё

sqlBulkCopy.WriteToServer(reader)
вызовет это исключение, если в таблице есть два непрерывных столбца, оба типа Char(1) или nvarchar(nn), и оба имеют NULL. Иногда изменение SqlBulkCopy.BatchSize заставляет его работать, но во многих случаях это не работает.
После упрощения у меня есть следующий тестовый пример, который можно воспроизвести на двух серверах:
  • Создайте таблицу, как показано ниже: (протестировано на SQL Server 2012 SP 4 и SQL Server 2016 SP2)

    Код: Выделить всё

     IF OBJECT_ID('dbo.TestTable', 'U') IS NOT NULL
    DROP TABLE dbo.TestTable;
    
    CREATE TABLE [dbo].[TestTable]
    (
    [value2] [char](1) NULL,
    [value1] [char](1) NULL
    ) ON [PRIMARY]
    GO
    
    DECLARE @i int = 0
    
    WHILE @i < 262
    BEGIN
    SET @i = @i + 1
    
    INSERT INTO [dbo].[TestTable]([value2], [value1])
    VALUES (null, null)
    END
    
  • Код консоли C# (.net framework 4.7), как показано ниже

    Код: Выделить всё

     class Program
    {
    // [change here]
    static string sourceConn = @"Server={YourServer};Database={YourDatabase};User ID={userYourName};Password={yourPassword};connect timeout=15";
    
    static void Main(string[] args)
    {
    CopyTable(sourceConn, sourceConn, "TestTable", "testTableBAK");
    Console.ReadLine();
    }
    
    static void CopyTable(string sConnSource, string sConnDest, string sTableSource, string sTableDest)
    {
    if (IsTableExist(sConnDest, sTableDest))
    {
    RunNonQuerySQL(sConnDest, "DROP TABLE " + sTableDest);
    Console.WriteLine($"existing table  {sTableDest} dropped");
    }
    
    CopySchema(sConnDest, sTableSource, sTableDest);
    
    using (SqlConnection connSource = new SqlConnection(sConnSource))
    {
    connSource.Open();
    SqlCommand cmd = new SqlCommand();
    cmd.Connection = connSource;
    cmd.CommandText = "SELECT * FROM " + sTableSource;
    
    // using (SqlBulkCopy sqlBulkCopy = new SqlBulkCopy(sConnDest, SqlBulkCopyOptions.KeepNulls | SqlBulkCopyOptions.KeepIdentity))
    using (SqlBulkCopy sqlBulkCopy = new SqlBulkCopy(sConnDest))
    {
    // sqlBulkCopy.BatchSize = 1380; // this optional setting will work if set value smaller than 1397 for testTable on my new server (SQL server  13.0.5102.14)
    // sqlBulkCopy.BatchSize = 261; // this optional setting will work if set value smaller than 261 for testTable on 2 older server (SQL server  11.0.7001)
    sqlBulkCopy.DestinationTableName = sTableDest;
    SqlDataReader reader = cmd.ExecuteReader();
    
    try
    {
    // exception here
    sqlBulkCopy.WriteToServer(reader);
    Console.WriteLine("table copied");
    }
    catch (SqlException ex)
    {
    Console.WriteLine(ex.Message);
    }
    
    sqlBulkCopy.Close();
    }
    }
    }
    
    static bool IsTableExist(string sConn, string sTableName)
    {
    bool result = false;
    
    using (SqlConnection conn = new SqlConnection(sConn))
    {
    conn.Open();
    SqlCommand cmd = new SqlCommand();
    string[] s = sTableName.Split('.');
    
    if (s.Length > 1)
    {
    cmd.CommandText = "select count (*) as counter from information_schema.tables where table_name = '" + s[1] + "' and TABLE_SCHEMA='" + s[0] + "'";
    }
    else
    {
    cmd.CommandText = "select count (*) as counter from information_schema.tables  where table_name = '" + sTableName + "'";
    }
    cmd.Connection = conn;
    var count = Convert.ToInt32(cmd.ExecuteScalar());
    result = count >  0;
    }
    
    return result;
    }
    
    static bool RunNonQuerySQL(string sConn, string sSQL)
    {
    bool result = false;
    
    using (SqlConnection conn = new SqlConnection(sConn))
    {
    conn.Open();
    
    SqlCommand cmd = new SqlCommand();
    cmd.CommandText = sSQL;
    cmd.Connection = conn;
    
    var count = cmd.ExecuteNonQuery();
    result = true;
    }
    
    return result;
    }
    
    static public bool CopySchema(string sConn, string sTableSource, string sTableDest)
    {
    return RunQuerySQL(sConn, "select * into " + sTableDest + " from " + sTableSource + " where 1=2");
    }
    
    static public bool RunQuerySQL(string sConn, string sSQL)
    {
    using (SqlConnection conn = new SqlConnection(sConn))
    {
    conn.Open();
    
    SqlCommand cmd = new SqlCommand();
    cmd.CommandText = sSQL;
    cmd.Connection = conn;
    
    SqlDataReader reader = cmd.ExecuteReader();
    
    if (reader.Read())
    {
    return true;
    }
    else
    {
    return false;
    }
    }
    }
    }
    


Подробнее здесь: https://stackoverflow.com/questions/656 ... e-bcp-clie
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»