Я пытаюсь перенести данные с Sql Server в базу данных Sybase 16.0 с помощью .net DLL, поставляемых с установкой Sybase (Sybase.AdoNet4.AseClient.dll версии 16.0.02).
Чтобы упростить задачу, я пытаюсь скопировать значения из таблицы с одним столбцом INT.
--source table (MSSQL)
CREATE TABLE [dbo].[TO_INTS](
[TO_INT] [int] NULL,
[TO_INT2] [int] NULL,
[NAME] [varchar](50) NULL,
[DT] [datetime] NULL
) ON [PRIMARY]
to
--target table (Sybase)
CREATE TABLE dbo.TO_INTS
(
FROM_INT INT NOT NULL
)
ON 'default'
Я использую код:
public void BulkCopyFromSqlServer(string sourceConnectionString, string targetConnectionString)
{
SqlConnection sourceConnection = null;
AseConnection targetConnection = new AseConnection(targetConnectionString);
IDataReader dataSource=null;
try
{
targetConnection.Open();
MssqlCommand.GetDataReader(sourceConnectionString, out sourceConnection, out dataSource); //see below
AseBulkCopy blk = new AseBulkCopy(targetConnection);
blk.BulkCopyTimeout = 1200;
blk.DestinationTableName = "TO_INTS";
blk.ColumnMappings.Clear();
blk.ColumnMappings.Add(new AseBulkCopyColumnMapping(0,0));
blk.WriteToServer(dataSource); // System.ArgumentException thrown here.
blk.Close();
}
catch (AseException ex)
{
Console.WriteLine(ex.Message);
}
finally
{
sourceConnection.Dispose();
targetConnection.Dispose();
}
}
//MssqlCommand.GetDataReader(sourceConnectionString, out sourceConnection, out dataSource):
public static void GetDataReader(string sqlServerConnectionString, out SqlConnection conn, out IDataReader reader)
{
conn = new SqlConnection(sqlServerConnectionString);
conn.Open();
SqlCommand cmd = new SqlCommand("select * from TO_INTS", conn);
cmd.CommandTimeout = 60;
reader = cmd.ExecuteReader();
}
Исключение System.ArgumentException возникает, когда WriteToServer()
вызывается с сообщением "Value does not fall within the expected range
". Трассировка стека интересна тем, что похоже, что Sybase DLL не может разрешить имя столбца БД, используя индекс, указанный в сопоставлении, что кажется странным:
at Sybase.Data.AseClient.AseBulkCopy.GetDBColName(String clientColName, Int32 clientColInx)
at Sybase.Data.AseClient.AseBulkCopy.GenerateInsertCmdByReaderMetaInfo(DataTable rowFmt)
at Sybase.Data.AseClient.AseBulkCopy.WriteToServer(IDataReader reader)
Я выполнил тот же процесс для Sybase> Sql Server (почти построчно, но с переключением соответствующих DLL), и это работает.
Я упускаю что-то очевидное?