我的旧软件中有太多免费表,需要将其中一些表连接到sql,以传输信息并在其他软件中使用。
答案 0 :(得分:1)
虽然您的问题是有关如何使用OpenRowSet进行此操作的,但我会忘记使用OpenRowset或OpenQuery(两者中最好的一个)获取VFP数据。可能32位或64位导入\导出向导也不起作用。至少在Windows 10之前,所有这些功能在旧时代都可以成功运行。我不知道它们已经更改了什么,现在它们都失败了(我在Windows 7下有大量的OpenRowset,OpenQuery示例)。 您可以尝试将Sybase ADS驱动程序与OpenRowset和OpenQuery一起使用。
幸运的是,有许多解决方法。一些变通办法使用诸如access和excel之类的中间体,但是恕我直言,它们是过大的。
如果您使用的是VFP本身,最简单的方法是在VFP中执行此操作,在VFP中,这是针对SQL Server执行的一系列“自动动态生成”代码。
另一个选择(我赞成)是使用一些C#代码,该代码将使用“ SqlBulkCopy”类进行传输。对于通用解决方案,您可以:
这里有一个示例,该示例不读取架构,而是在服务器上创建具有已知架构的临时表,并且仅出于演示目的创建了示例映射(如果您认为市场上从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