从SQL表记录创建. dbf文件

本文关键字:dbf 文件 创建 记录 SQL | 更新日期: 2023-09-27 18:12:55

我想从SQL表记录中创建一个.DBF文件。

例如SQL中有一个名为CountryMaster的表,它有5列:

  1. ID int identity(1,1)
  2. 名称varchar (100)
  3. 细节varchar (200)
  4. 状态位
  5. CreatedDate datetime

它有100行

我怎么能导出这些记录与标题在.DBF文件从c# ?

注意:创建的.DBF文件大小必须非常紧凑。

从SQL表记录创建. dbf文件

您可以查看Xbase Data文件(*.dbf)结构并编写自己的代码,但我已经完成了实现并使用了多年。你可以在GitHub上找到它


如何使用库

在名为 dbfffile .cs的文件中有一些write方法。你可以使用它们中的任何一个。我将解释其中的一些:

First Write Method

另存DataTabledbf文件:

static void Write(string fileName, System.Data.DataTable table, Encoding encoding)
  • fileName:是您希望保存.dbf输出文件的位置。
  • table:是您从SQL Server或任何其他来源读取的数据。
  • encoding:保存字符串数据时使用的编码

第二种写方法

保存List<T>到dbf文件

static void Write<T>(string fileName,
                                    List<T> values,
                                    List<Func<T, object>> mapping,
                                    List<DbfFieldDescriptor> columns,
                                    Encoding encoding)

读取数据库并将结果保存到某个类类型中,然后使用此方法将类值保存到dbf文件中。下面是它的参数说明:

  • fileName:要保存的dbf文件名
  • values:您的数据作为T类型对象的列表保存到dbf文件
  • mapping:一个函数列表,告诉这个方法如何从类类型中检索数据。
  • columns: dbf列信息
  • encoding: dbf文件的编码。

第二个写方法示例

由于第一种方法是直接的,所以我提供了关于第二种写入方法的示例。假设您希望将List<MyClass>数据保存到dbf文件中。下面是代码

class MyClass
{
    public int Id {get;set;}
    public string Name {get;set;}
}

现在可以将List<MyClass>保存到dbf文件中,如下所示:

var idColumn = DbfFieldDescriptors.GetIntegerField("Id");
var nameColumn = DbfFieldDescriptors.GetStringField("Name");
var columns = new List<DbfFieldDescriptor>() { idColumn, nameColumn };
Func<MyClass, object> mapId = myClass => myClass.Id;
Func<MyClass, object> mapName = myClass => myClass.Name;
var mapping = new List<Func<MyClass, object>>() { mapId, mapName };
List<MyClass> values = new List<MyClass>();
values.Add(new MyClass() { Id = 1, Name = "name1" });
DbfFileFormat.Write(@"C:'yourFile.dbf", values, mapping, columns, Encoding.ASCII);

同样使用这个库,你可以读取dbf文件,而你的代码不能依赖于Microsoft.Jet.OLEDB或其他任何东西

享受它。

您需要的大部分信息都可以在插入.dbf文件的问题中看到,因为它展示了如何在创建.dbf文件时创建表并向其中插入值。您将需要对指定的字段进行一些修改,但是该页面描述了您需要的所有内容。

我想帮忙。但是,我将坚持使用OLEDB用于VPF的普通过程。

CREATE TABLE DBF

可以是.DBF

的创建表脚本
CREATE TABLE "C:'test.dbf" ([ID] Numeric(18,0), [Name] Char(100) NULL, [Details] Char(200) NULL, [Status] Logical NULL, [CreateDate] DATETIME NULL)

然后,您可以像下面这样从OLE DB脚本调用它。

    string vpfScript = "CREATE TABLE '"C:'test.dbf'" ([ID] Numeric(18,0), [Name] Char(100) NULL, [Details] Char(200) NULL, [Status] Logical NULL, [CreateDate] DATETIME NULL)";
    string connectionString = @"Provider=VFPOLEDB.1;Data Source=C:'test.dbf";
    OleDbConnection connection = new OleDbConnection(connectionString);
    using (OleDbCommand scriptCommand = connection.CreateCommand())
    {
         connection.Open();
         scriptCommand.CommandType = CommandType.StoredProcedure;
         scriptCommand.CommandText = "ExecScript";
         scriptCommand.Parameters.Add("myScript", OleDbType.Char).Value = vfpScript;
         scriptCommand.ExecuteNonQuery();
    }

IMPORT ROW IN TABLE

要在DBF表中导入行,它不像我们在其他DB中使用的SQL脚本那么远。

    string vpfScript = "INSERT INTO '"C:'test.dbf'" ([ID], [Name], [Details], [Status], [CreateDate]) VALUES (1,'test john','test details',.t.,{^2015-09-15)";
    string connectionString = @"Provider=VFPOLEDB.1;Data Source=C:'test.dbf";
    OleDbConnection connection = new OleDbConnection(connectionString);
    using (OleDbCommand scriptCommand = connection.CreateCommand())
    {
        connection.Open();
        scriptCommand.CommandType = CommandType.StoredProcedure;
        scriptCommand.CommandText = "ExecScript";
        scriptCommand.Parameters.Add("myScript", OleDbType.Char).Value = vfpScript;
        scriptCommand.ExecuteNonQuery();
    }

您现在可以根据需要更改值,就像下面的用法一样。

    DataTable dt = new DataTable(); // assuming this is already populated from your SQL Database.
    StringBuilder buildInsert = new StringBuilder();
    string connectionString = @"Provider=VFPOLEDB.1;Data Source=C:'test.dbf";
    OleDbConnection connection = new OleDbConnection(connectionString);
    using (OleDbCommand scriptCommand = connection.CreateCommand())
    {
         connection.Open();
         foreach(DataRow dr in dt.Rows)
         {
             string id = dr["ID"].ToString();
             string name = dr["Name"].ToString();
             string details = dr["Details"].ToString();
             string status = Convert.ToBoolean(dr["Status"]) ? ".t." : ".f.";
             string createDate = "{^" + Convert.ToDateTime(dr["CreateDate"]).ToString("yyyy-MM-dd") + "}";
             builderInsert.Append("INSERT INTO '"C:'test.dbf'" ([ID], [Name], [Details], [Status], [CreateDate]) VALUES (" + id + ",'"" + name + "'",'"" + details + "'"," + status + "," + createDate + ")" + Environment.NewLine);
             scriptCommand.CommandType = CommandType.StoredProcedure;
             scriptCommand.CommandText = "ExecScript";
             scriptCommand.Parameters.Add("myScript", OleDbType.Char).Value = builderInsert;
             scriptCommand.ExecuteNonQuery();
             builderInsert = "";
          }
     }

如果您还有其他问题,请告诉我。别忘了在你的机器上安装这个。VFP OLE DB

为您提供c#解决方案,我将从下载Microsoft Visual Foxpro OleDb Provider开始,它与。dbf表一起工作。

在c#代码的顶部添加
using System.Data.SqlClient;
using System.Data.OleDb;

然后,在方法中移动数据

    void MoveFromSQLToDBF()
    {    
        // have a table to pull down your SQL Data...
        var dataFromSQL = new DataTable();
        // However your connection to your SQL-Server
        using (var sqlConn = new  SqlConnection("YourSQLConnectionString"))
        {
           using (var sqlCmd = new SqlCommand("", sqlConn))
           {
              // Get all records from your table
              sqlCmd.CommandText = "select * from CountryMaster";
              sqlConn.Open();
              var sqlDA = new SqlDataAdapter();
              // populate into a temp C# table
              sqlDA.Fill(dataFromSQL);
              sqlConn.Close();
           }
        }
        // Now, create a connection to VFP 
        // connect to a PATH where you want the data.
        using (var vfpConn = new OleDbConnection(@"Provider=VFPOLEDB.1;Data Source=C:'SomePathOnYourMachine'"))
        {
           using (var vfpCmd = new OleDbCommand("", vfpConn))
           {
              // Create table command for VFP
              vfpCmd.CommandText = "CREATE TABLE testFromSQL ( ID Numeric(18,0), [Name] Char(100) NULL, [Details] Char(200) NULL, [Status] Logical NULL, [CreateDate] DATETIME NULL)";
              vfpConn.Open();
              vfpCmd.ExecuteNonQuery();
              // Now, change the command to a SQL-Insert command, but PARAMETERIZE IT.
              // "?" is a place-holder for the data
              vfpCmd.CommandText = "insert into testFromSQL "
                 + "( ID, [Name], [Details], [Status], [CreateDate]) values ( ?, ?, ?, ?, ? )";
              // Parameters added in order of the INSERT command above.. 
              // SAMPLE values just to establish a basis of the column types
              vfpCmd.Parameters.Add( new OleDbParameter( "parmID", 10000000 ));
              vfpCmd.Parameters.Add( new OleDbParameter( "parmName", "sample string" ));
              vfpCmd.Parameters.Add(new OleDbParameter( "parmDetails", "sample string" ));
              vfpCmd.Parameters.Add(new OleDbParameter( "parmStatus", "sample string" ));
              vfpCmd.Parameters.Add( new OleDbParameter( "parmCreateDate", DateTime.Now ));
              // Now, for each row in the ORIGINAL SQL table, apply the insert to VFP
              foreach (DataRow dr in dataFromSQL.Rows)
              {
                 // set the parameters based on whatever current record is
                 vfpCmd.Parameters[0].Value = dr["ID"];
                 vfpCmd.Parameters[1].Value = dr["Name"];
                 vfpCmd.Parameters[2].Value = dr["Details"];
                 vfpCmd.Parameters[3].Value = dr["Status"];
                 vfpCmd.Parameters[4].Value = dr["CreateDate"];
                 // execute it
                 vfpCmd.ExecuteNonQuery();
              }
              // Finally, for compactness, use a VFP Script to copy to Excel (CSV) format
              using (var vfpCmd2 = new OleDbCommand("", vfpConn))
              {
                 vfpCmd2.CommandType = CommandType.StoredProcedure;
                 vfpCmd2.CommandText = "ExecScript";
                 vfpCmd2.Parameters.Add(new OleDbParameter( "csvScript", 
@"Use testFromSQL
copy to YourCompactFile.csv type csv
use" ));
                 vfpCmd2.ExecuteNonQuery();
              }
              // close VFP connection
              vfpConn.Close();
           }
        }
    }

由于OleDb不支持复制类型CSV,我找到了这篇关于S/O转储为CSV格式的文章