从SQL表记录创建.DBF文件
我想从SQL表记录创建一个.DBF
文件。
例如,如果在SQL中有一个名为CountryMaster
的表,它有5列:
- ID int identity(1,1)
- 名称varchar(100)
- 详细信息varchar(200)
- 状态位
- CreatedDate日期时间
它有100行。
如何使用C#中的.DBF
文件中的标头导出这些记录?
注意:创建的.DBF
文件大小必须非常紧凑。
您可以看到Xbase数据文件(* .dbf)结构并编写自己的代码,但我已经完成了实现,并且已经使用了多年。 在这里你可以在GitHub上找到它
如何使用该库
在名为DbfFile.cs的文件中有一些写入方法。 你可以使用它们中的任何一个。 我将解释其中一些:
第一种写法
将DataTable
另存为dbf文件:
static void Write(string fileName, System.Data.DataTable table, Encoding encoding)
-
fileName
:是您希望保存.dbf
输出文件的位置。 -
table
:是您从SQL Server或任何其他来源读取的数据。 -
encoding
:保存字符串数据时使用的编码
第二种写方法
将List
保存到dbf文件中。
static void Write(string fileName, List values, List> mapping, List columns, Encoding encoding)
读取数据库并将结果保存到某个类类型,然后使用此方法将类值保存到dbf文件。 这是对它的参数的描述:
-
fileName
:要保存的dbf文件名 -
values
:您的数据作为要保存到dbf文件中的类型T
的对象列表 -
mapping
:告诉此方法如何从类类型中检索数据的函数列表。 -
columns
:dbf列信息 -
encoding
:dbf文件的编码。
第二种写方法的示例
由于第一种方法是直接的,我提供了第二种写方法的示例。 考虑您要将List
数据保存到dbf文件中。 这是代码
class MyClass { public int Id {get;set;} public string Name {get;set;} }
现在您可以将List
保存到dbf文件中,如下所示:
var idColumn = DbfFieldDescriptors.GetIntegerField("Id"); var nameColumn = DbfFieldDescriptors.GetStringField("Name"); var columns = new List() { idColumn, nameColumn }; Func mapId = myClass => myClass.Id; Func mapName = myClass => myClass.Name; var mapping = new List>() { mapId, mapName }; List values = new List (); values.Add(new MyClass() { Id = 1, Name = "name1" }); DbfFileFormat.Write(@"C:\yourFile.dbf", values, mapping, columns, Encoding.ASCII);
同样使用此库,您可以读取dbf文件,并且您的代码不依赖于
Microsoft.Jet.OLEDB
或其他任何内容。
好好享受。
大多数情况下,您可以在Trouble with Insert Into .dbf文件中看到所需的所有信息,因为它显示了如何创建表并在创建.dbf文件时将值插入其中。 您需要对指定的字段进行一些修改,但页面会描述您需要的所有内容。
我想帮忙。 然而,id坚持使用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行
要导入DBF表中的行,它不像我们在其他数据库中执行的常见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#解决方案,我首先要下载与.DBF表一起使用的Microsoft Visual Foxpro OleDb Provider 。
在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不支持复制TYPE CSV,我在S / O上发现此post为您转储为CSV格式