我需要将一些CSV文件导入MDB数据库中的临时表。 这些文件来自ASP.NET Web应用程序上的文件上载。
这是我的CSV文件:
"Operating Unit Organization Name";"Year";"Sales Rep Name";"Date";"Week";"Product Number";"Account Name";"Customer Number";"Corporate Brand";"Brand";"Ordered Quantity";"Amount"
"IT Operating Unit";2014;"Name-561004";2014-02-21;"2014 Week08";"123456+";"Buyer name";"456789";"Corp Brand";"Brand";4;147,52
"IT Operating Unit";2014;"Name-561004";2014-02-21;"2014 Week08";"123.012EXP";"Buyer name";"789123";"Corp Brand";"Brand";10;204,9
"IT Operating Unit";2014;"Name-561004";2014-02-17;"2014 Week08";"101S-3";"Buyer name";"234567";"Another Corp Brand";"Another Brand";30;237,5
这是生成 schema.ini
文件的方法。由于它必须包含CSV文件的名称,因此每次上传新CSV时都会生成新的模式文件,因为我需要将它们全部保存在具有特定名称的文件夹中。
private void CreateCsvSchemaFile()
{
using (FileStream fs = new FileStream(Path.GetDirectoryName(FilePath) + "\\schema.ini", FileMode.Create, FileAccess.Write))
{
using (StreamWriter sw = new StreamWriter(fs))
{
sw.WriteLine("[" + Path.GetFileName(FilePath) + "]");
sw.WriteLine("ColNameHeader=True");
//sw.WriteLine("MaxScanRows=0");
sw.WriteLine("Format=Delimited(;)");
sw.WriteLine("DateTimeFormat=yyyy-MM-dd");
sw.WriteLine("CharacterSet=ANSI");
sw.WriteLine("DecimalSymbol=,");
sw.WriteLine("Col1=\"Operating Unit Organization Name\" Text Width 255");
sw.WriteLine("Col2=\"Year\" Long");
sw.WriteLine("Col3=\"Sales Rep Name\" Text Width 255");
sw.WriteLine("Col4=\"Date\" DateTime");
sw.WriteLine("Col5=\"Week\" Text Width 255");
sw.WriteLine("Col6=\"Product Number\" Text Width 255");
sw.WriteLine("Col7=\"Account Name\" Text Width 255");
sw.WriteLine("Col8=\"Customer Number\" Text Width 255");
sw.WriteLine("Col9=\"Corporate Brand\" Text Width 255");
sw.WriteLine("Col10=\"Brand\" Text Width 255");
sw.WriteLine("Col11=\"Ordered Quantity\" Long");
sw.WriteLine("Col12=\"Amount\" Currency");
sw.Close();
sw.Dispose();
}
fs.Close();
fs.Dispose();
}
}
schema.ini
文件始终正确生成,实际上db上的表是使用正确的字段名称和类型创建的。
这是执行CSV导入的方法。
private void ImportCsvIntoTemp()
{
try
{
CreateCsvSchemaFile();
string query = @"SELECT * INTO TEMP_CSV
FROM [Text;HDR=no;Database={0}].[{1}]";
query = String.Format(query, Path.GetDirectoryName(FilePath), Path.GetFileName(FilePath));
AccessDb.Query(AccessDbConnString, query);
}
catch (Exception ex)
{
string message = String.Format("CSV file import failed. Inner Exception: {0}", ex.Message);
throw new ImportFailedException(message);
}
}
表TEMP_CSV
已正确创建但未加载任何数据。
相反,如果我用Access打开MDB,我会看到8个空行。我尝试更改schema.ini
文件中的一些参数,例如添加/删除MaxScnaRows=0
,CharacterSet
等等...在查询中我还尝试更改{{1但是我总是得到相同的结果。
- EDIT添加了AccessDb.Query()方法和数据库连接字符串 -
我没有包含FROM Properties
方法,因为Query()
它只是一个“DB层”类,它包含创建与db的连接并执行带/不带参数的查询/列表查询/标量的方法。我在其他页面以及许多其他应用程序中使用此类。
无论如何,这是AccessDb
方法。
AccessDb.Query()
这是我的数据库连接字符串,在public static void Query(string connString, string query)
{
OleDbConnection conn = new OleDbConnection(connString);
try
{
conn.Open();
OleDbCommand cmd = conn.CreateCommand();
cmd.CommandText = query;
cmd.ExecuteNonQuery();
cmd.Dispose();
}
catch (OleDbException odbEx)
{
throw odbEx;
}
catch (Exception ex)
{
throw ex;
}
finally
{
conn.Dispose();
conn.Close();
}
}
文件中配置。
Web.config
答案 0 :(得分:3)
您发布的代码基本上是正确的。我将其复制并粘贴到一个新的C#项目中,并将其调整到足以让它运行。当我确实让它运行时,它工作正常,创建新表并将所有三(3)行导入其中。
主要区别在于我只使用以下代码来执行SELECT * INTO ...
查询。而不是......
AccessDb.Query(AccessDbConnString, query);
......我用过......
using (OleDbConnection con = new OleDbConnection())
{
con.ConnectionString =
@"Provider=Microsoft.Jet.OLEDB.4.0;" +
@"Data Source=C:\Users\Public\test\CsvImportTest\MyDb.mdb;";
con.Open();
using (OleDbCommand cmd = new OleDbCommand())
{
cmd.Connection = con;
cmd.CommandText = query;
cmd.ExecuteNonQuery();
}
con.Close();
}
完整的代码是:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Data.OleDb;
namespace CsvImportTest
{
class Program
{
static string FilePath = @"C:\Users\Public\test\CsvImportTest\TestData.csv";
static void Main(string[] args)
{
ImportCsvIntoTemp();
Console.WriteLine("Done.");
}
private static void ImportCsvIntoTemp()
{
try
{
CreateCsvSchemaFile();
string query = @"SELECT * INTO TEMP_CSV
FROM [Text;HDR=no;Database={0}].[{1}]";
query = String.Format(query, Path.GetDirectoryName(FilePath), Path.GetFileName(FilePath));
//AccessDb.Query(AccessDbConnString, query);
using (OleDbConnection con = new OleDbConnection())
{
con.ConnectionString =
@"Provider=Microsoft.Jet.OLEDB.4.0;" +
@"Data Source=C:\Users\Public\test\CsvImportTest\MyDb.mdb;";
con.Open();
using (OleDbCommand cmd = new OleDbCommand())
{
cmd.Connection = con;
cmd.CommandText = query;
cmd.ExecuteNonQuery();
}
con.Close();
}
}
catch (Exception ex)
{
string message = String.Format("CSV file import failed. Inner Exception: {0}", ex.Message);
Console.WriteLine(message);
//throw new ImportFailedException(message);
}
}
private static void CreateCsvSchemaFile()
{
using (FileStream fs = new FileStream(Path.GetDirectoryName(FilePath) + "\\schema.ini", FileMode.Create, FileAccess.Write))
{
using (StreamWriter sw = new StreamWriter(fs))
{
sw.WriteLine("[" + Path.GetFileName(FilePath) + "]");
sw.WriteLine("ColNameHeader=True");
//sw.WriteLine("MaxScanRows=0");
sw.WriteLine("Format=Delimited(;)");
sw.WriteLine("DateTimeFormat=yyyy-MM-dd");
sw.WriteLine("CharacterSet=ANSI");
sw.WriteLine("DecimalSymbol=,");
sw.WriteLine("Col1=\"Operating Unit Organization Name\" Text Width 255");
sw.WriteLine("Col2=\"Year\" Long");
sw.WriteLine("Col3=\"Sales Rep Name\" Text Width 255");
sw.WriteLine("Col4=\"Date\" DateTime");
sw.WriteLine("Col5=\"Week\" Text Width 255");
sw.WriteLine("Col6=\"Product Number\" Text Width 255");
sw.WriteLine("Col7=\"Account Name\" Text Width 255");
sw.WriteLine("Col8=\"Customer Number\" Text Width 255");
sw.WriteLine("Col9=\"Corporate Brand\" Text Width 255");
sw.WriteLine("Col10=\"Brand\" Text Width 255");
sw.WriteLine("Col11=\"Ordered Quantity\" Long");
sw.WriteLine("Col12=\"Amount\" Currency");
sw.Close();
sw.Dispose();
}
fs.Close();
fs.Dispose();
}
}
}
}
检查您用于实际执行SELECT * INTO ...
查询的代码,看看您是否可以找到代码与我的代码之间存在重大差异。
答案 1 :(得分:1)
最后我发现了问题所在。
首先,您应该注意要导入的文件的字符集。如果将schema.ini
文件设置为ANSI,则必须确保是ANSI。
然后我也遇到了"DecimalSymbol=,"
选项的麻烦。删除后导入工作正常。无论如何,使用我的语言环境设置(Italia(Italiano))它应该是正确的,因为小数符号是','
...
所以这是创建schema.ini
文件的最终方法。
private void CreateCsvSchemaFile()
{
using (FileStream fs = new FileStream(Path.GetDirectoryName(FilePath) + "\\schema.ini", FileMode.Create, FileAccess.Write))
{
using (StreamWriter sw = new StreamWriter(fs))
{
sw.WriteLine("[" + Path.GetFileName(FilePath) + "]");
sw.WriteLine("ColNameHeader=True");
sw.WriteLine("Format=Delimited(;)");
sw.WriteLine("DateTimeFormat=yyyy-MM-dd");
sw.WriteLine("CharacterSet=ANSI");
sw.WriteLine("Col1=\"Operating Unit Organization Name\" Text Width 255");
sw.WriteLine("Col2=\"Year\" Long");
sw.WriteLine("Col3=\"Sales Rep Name\" Text Width 255");
sw.WriteLine("Col4=\"Date\" DateTime");
sw.WriteLine("Col5=\"Week\" Text Width 255");
sw.WriteLine("Col6=\"Product Number\" Text Width 255");
sw.WriteLine("Col7=\"Account Name\" Text Width 255");
sw.WriteLine("Col8=\"Customer Number\" Text Width 255");
sw.WriteLine("Col9=\"Corporate Brand\" Text Width 255");
sw.WriteLine("Col10=\"Brand\" Text Width 255");
sw.WriteLine("Col11=\"Ordered Quantity\" Long");
sw.WriteLine("Col12=\"Amount\" Currency");
sw.Close();
sw.Dispose();
}
fs.Close();
fs.Dispose();
}
}