#sql #sql-server #ssis #odbc #visual-foxpro
#sql #sql-сервер #служба ssis #odbc #visual-foxpro
Вопрос:
Я пытаюсь синхронизировать базу данных Visual FoxPro с базой данных SQL Server.
Я использую мастер импорта и экспорта SQL Server (из SQL Server Data Tools).
Когда я нажимаю «Редактировать сопоставления …» Сначала у меня было 4 ошибки с той же проблемой, затем я изменил несколько значений в ProviderDescriptors.xml и в итоге получилось вот что:
<dtm:ColumnSchemaAttributes
NameColumnName = "COLUMN_NAME"
OrdinalPositionColumnName="ORDINAL_POSITION"
DataTypeColumnName = "TYPE_NAME"
MaximumLengthColumnName = "LENGTH"
NumericPrecisionColumnName = "PRECISION"
NumericScaleColumnName = "SCALE"
NullableColumnName="NULLABLE"
NumberOfColumnRestrictions="4"
/>
Теперь единственная ошибка включена OrdinalPositionColumnName
Ошибка: The column attribute "ORDINAL_POSITION" is not valid
Для какого значения использовать OrdinalPositionColumnName
(при использовании драйвера Visual FoxPro ODBC)?
Спасибо за помощь!
Комментарии:
1. Нет драйвера Foxpro ODBC (после версии 6.x). Вместо этого используйте драйвер VFPOLEDB.
2. @CetinBasoz Спасибо за ваш ответ! Я не мог использовать
Microsoft OLE DB Provider for Visual FoxPro
, потому что он выходит из строя, когда я выбираю это и нажимаюProperties...
3. Ну, я никогда не использовал его с SSIS. Я всегда сам пишу свои коды SQL server to-from на VFP или C #, Go, … Вы можете попробовать VFPOLEDB на связанных серверах. (Кстати, это 32-разрядный драйвер, при 64 битах он не будет работать).
4. Мой сервер MS SQl имеет 64 бита, так что, вероятно, это не сработает, как мне написать программу на C # для импорта базы данных таблиц без FVP на SQL Server?
5. Вы могли бы использовать класс SqlBulkCopy. Я могу дать вам пример кода в качестве ответа, если хотите.
Ответ №1:
Вот пример:
void Main()
{
string sqlConnectionString = @"server=.SQLExpress;Trusted_Connection=yes;Database=Test";
// c:MyDataFoldermyTable.dbf
string dataPath = @"c:MyDataFolder";
string tableName = @"MyTable";
Stopwatch sw = new Stopwatch(); // just for timing the sample run
sw.Start();
using (OleDbConnection cn = new OleDbConnection("Provider=VFPOLEDB;Data Source=" dataPath))
using (SqlConnection scn = new SqlConnection(sqlConnectionString))
{
OleDbCommand cmd = new OleDbCommand($"select * from {tableName}", cn);
SqlBulkCopy sbc = new SqlBulkCopy(scn, SqlBulkCopyOptions.TableLock, null);
// Needed if VFP-SQL Server tables' field count or names are different
// ie: LName in VFP might be LastName in SQL server
// or VFP might have 10 fields when SQL server 8
// VFP column names on left, SQL server column names on right
sbc.ColumnMappings.Add("Category", "[Category]");
sbc.ColumnMappings.Add("Activity", "[Activity]");
sbc.ColumnMappings.Add("PersonId", "[PersonId]");
sbc.ColumnMappings.Add("FirstName", "[FirstName]");
sbc.ColumnMappings.Add("MidName", "[MidName]");
sbc.ColumnMappings.Add("LastName", "[LastName]");
sbc.ColumnMappings.Add("Email", "[Email]");
cn.Open();
scn.Open();
// Since this is a sample, instead of wrting to a table
// creating and writing to a global temporary table
// You can see this table's data, connecting to the same database (global temp)
SqlCommand createTemp = new SqlCommand();
createTemp.CommandText = @"create table ##PersonData
(
[Id] int identity primary key,
[Category] varchar(50),
[Activity] varchar(50) default 'NullOlmasin',
[PersonId] varchar(50),
[FirstName] varchar(50),
[MidName] varchar(50),
[LastName] varchar(50),
[Email] varchar(50)
)";
createTemp.Connection = scn;
createTemp.ExecuteNonQuery();
OleDbDataReader rdr = cmd.ExecuteReader();
sbc.NotifyAfter = 100000;
sbc.BatchSize = 1000;
sbc.BulkCopyTimeout = 10000;
sbc.DestinationTableName = "##PersonData";
sbc.SqlRowsCopied = (sender, e) =>
{
Console.WriteLine("-- Copied {0} rows to {1}.[{2} milliseconds]",
e.RowsCopied,
((SqlBulkCopy)sender).DestinationTableName,
sw.ElapsedMilliseconds);
};
sbc.WriteToServer(rdr);
if (!rdr.IsClosed) { rdr.Close(); }
cn.Close();
scn.Close();
}
sw.Stop();
Console.WriteLine($"Done in {sw.ElapsedMilliseconds} milliseconds.");
}
Ответ №2:
Я знаю, что уже немного поздно, но я наткнулся на ваш вопрос, когда сам искал ответ, и я хотел задокументировать его здесь на случай, если в будущем кто-нибудь еще на моем месте будет искать эту проблему и найдет эту страницу.
Ответ — Radix
в контексте это выглядит так:
<dtm:ColumnSchemaAttributes
NameColumnName = "COLUMN_NAME"
OrdinalPositionColumnName="Radix"
DataTypeColumnName = "TYPE_NAME"
MaximumLengthColumnName = "LENGTH"
NumericPrecisionColumnName = "PRECISION"
NumericScaleColumnName = "SCALE"
NullableColumnName="NULLABLE"
NumberOfColumnRestrictions="4"
/>