Создать файл.DBF из записей таблицы SQL

Я хочу создать .DBF файл из записей таблицы SQL.

Например, если есть таблица с именем CountryMaster в SQL и имеет 5 столбцов:

  1. ID int идентичность (1,1)
  2. Имя варчар (100)
  3. Детали варчар (200)
  4. Бит состояния
  5. CreatedDate datetime

И это имеет 100 строк.

Как я могу экспортировать эти записи с заголовками в .DBF файл из C#?

ПРИМЕЧАНИЕ: создано .DBF Размер файла должен быть очень компактным.

4 ответа

Решение

Вы можете увидеть структуру файла данных 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<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. Вам нужно будет внести некоторые изменения в поля, которые вы указали, но на странице описано все, что вам нужно.

Чтобы предложить вам решение на 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 не поддерживает копирование TYPE CSV, я нашел этот пост в S/O, чтобы сделать дамп в формате CSV для вас

Я хотел бы помочь. Тем не менее, 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();
    }

Строка импорта в таблице

Чтобы импортировать строки в таблицу DBF, это не так, как обычные сценарии SQL, которые мы делаем в других DB.

    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

Другие вопросы по тегам