Хотя ваш вопрос о том, как это сделать с помощью OpenRowSet, я бы сказал, забудьте о получении данных VFP с использованием OpenRowset или OpenQuery (что было бы лучше из двух).Вероятно, 32-битные или 64-битные мастера импорта / экспорта тоже не будут работать.Все они успешно работали в старые добрые времена, по крайней мере, до Windows 10.Я не знаю, что они изменили, теперь все они терпят неудачу (у меня было множество рабочих OpenRowset, примеров OpenQuery под Windows 7).Вы можете попробовать драйвер Sybase ADS с OpenRowset и OpenQuery.
К счастью, есть много обходных путей.Некоторые обходные пути используют промежуточные звенья, такие как доступ и превосходство, но ИМХО они излишни.
Если вы используете сам VFP, проще всего сделать это из VFP, где это серия «автоматически генерируется на лету»код, выполняемый на SQL Server.
Еще один вариант (который я предпочитаю) - использовать некоторый код C #, который будет выполнять передачу с использованием класса "SqlBulkCopy".Для общего решения вы можете:
- Создать базу данных на сервере,
- Считать информацию о схеме таблицы VFP,
- Создать совместимую таблицу на сервере (то есть выможет потребоваться изменить типы данных),
- Создать информацию о сопоставлении столбцов,
- Массовая загрузка в таблицу
- Повторить процесс в цикле для всех таблиц.
Вот один пример, который не читает схему, а вместо этого создает временную таблицу на сервере с известной схемой и примером сопоставления только для демонстрационных целей (если вы считаете, что DBF для инструментов SQL Server на рынке превышает 100 $, неплохой стартер):
void Main()
{
string sqlConnectionString = @"server=.\SQLExpress;Trusted_Connection=yes;Database=Test";
string path = @"C:\PROGRAM FILES (X86)\MICROSOFT VISUAL FOXPRO 9\SAMPLES\Northwind";
DataTable tbl = new DataTable(); // just to show the results - sadece sonuclari gostermek icin
using (OleDbConnection cn = new OleDbConnection("Provider=VFPOLEDB;Data Source="+path))
using (SqlConnection scn = new SqlConnection( sqlConnectionString ))
{
// Creatint a temp SQL Server table for sampling.
// If the table already existed then this part wouldn't exist.
// We would simply insert then.
// gecici bir SQL server tablosu yaratiyoruz ornek icin.
// tablo zaten var ise bu kisim olmayacak. Sadece insert edecektik.
SqlCommand createTemp = new SqlCommand();
createTemp.CommandText = @"create table ##SqlBulkSample
(
[CustomerId] char(6),
[Company] varchar(50),
[Contact] varchar(50),
[Country] varchar(20)
)";
createTemp.Connection = scn;
scn.Open();
createTemp.ExecuteNonQuery();
// Get the data from VFP and write to server using SqlBulkCopy
// Excelden veriyi al ve SqlBulkCopy ile servera yaz
OleDbCommand cmd = new OleDbCommand("select CustomerId, CompanyName, ContactName, Country from Customers", cn);
SqlBulkCopy sbc = new SqlBulkCopy(scn, SqlBulkCopyOptions.TableLock,null);
// For demonstration purposes of column mapping,
// we have different count of fields with different field names and order.
// Without mapping, it would be a copy of the same structured data
// Column mapping'i orneklemek icin farkli sayi, isim ve sirada alanlarimiz var.
// Mapping olmasa idi ayni yapidaki veri kopyalaniyor olacakti.
sbc.ColumnMappings.Add(0,"[CustomerId]");
sbc.ColumnMappings.Add(1,"[Company]");
sbc.ColumnMappings.Add(2,"[Contact]");
sbc.ColumnMappings.Add(3,"[Country]");
cn.Open();
OleDbDataReader rdr = cmd.ExecuteReader();
//SqlBulkCopy properties
//With defaults or high values we wouldn't see any notification so
// for demoing purposes setting them to be extremely low
// SqlBulkCopy'nin propertyleri
// Varsayilan veya yuksek degerlerle hic geri bildirim
// almayacaktik, o nedenle bu degerleri oldukca kucuk
// degerlere kuruyoruz.
sbc.NotifyAfter = 20;
sbc.BatchSize = 10;
//sbc.BulkCopyTimeout = 10000;
sbc.DestinationTableName = "##SqlBulkSample";
// Notify in between
// Arada notification
sbc.SqlRowsCopied += (sender,e) =>
{
Console.WriteLine("-- Copied {0} rows to {1}.",
e.RowsCopied,
((SqlBulkCopy)sender).DestinationTableName);
};
// Write to server
// server'a yaz
sbc.WriteToServer(rdr);
if (!rdr.IsClosed) { rdr.Close(); }
cn.Close();
// Check that it is really written to server.
// Just for testing the sample.
// Server'a hakikaten yazildigini kontrol ediyoruz.
// Bu sadece ornekte test icin.
SqlCommand cmdRead = new SqlCommand("select * from ##SqlBulkSample", scn);
tbl.Load(cmdRead.ExecuteReader());
scn.Close();
}
// Show the data read from SQL server
// Serverdan okunanlari bir formda goster.
Form f = new Form();
DataGridView dgv = new DataGridView();
dgv.Location = new Point(0, 0);
dgv.Dock = DockStyle.Fill;
dgv.DataSource = tbl;
f.Controls.Add(dgv);
f.ClientSize = new Size(1024, 768);
f.ShowDialog();
}
А также, ваше программное обеспечение может напрямую использовать данные VFP, не передавая их в MS SQL Server (я не думаю, что вы захотите это сделать, но в любом случае).
HTH