вызовет это исключение, если в таблице есть два непрерывных столбца, оба типа 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), как показано ниже
У меня есть код, использующий SqlBulkCopy для клонирования множества таблиц, раньше он работал, но очень странно, недавно получил исключение.
Получил неверную длину столбца от клиента bcp для colid
Я выполнил поиск по этому исключению, но до сих пор не решил проблему. [code]sqlBulkCopy.WriteToServer(reader)[/code] вызовет это исключение, если в таблице есть два непрерывных столбца, оба типа Char(1) или nvarchar(nn), и оба имеют NULL. Иногда изменение SqlBulkCopy.BatchSize заставляет его работать, но во многих случаях это не работает. После упрощения у меня есть следующий тестовый пример, который можно воспроизвести на двух серверах: [list] [*]Создайте таблицу, как показано ниже: (протестировано на SQL Server 2012 SP 4 и SQL Server 2016 SP2) [code] 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 [/code]
[*]Код консоли C# (.net framework 4.7), как показано ниже [code] class Program { // [change here] static string sourceConn = @"Server={YourServer};Database={YourDatabase};User ID={userYourName};Password={yourPassword};connect timeout=15";
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();