如何使用openrowset在sqlserver 2012上导入/读取.dbf文件?

时间:2018-10-09 14:15:15

标签: sql-server database visual-foxpro dbf

我的旧软件中有太多免费表,需要将其中一些表连接到sql,以传输信息并在其他软件中使用。

1 个答案:

答案 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”类进行传输。对于通用解决方案,您可以:

  • 在服务器上创建数据库,
  • 读取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