C# 使用混合数据类型从CSV文件读取数据
只要每个“项目”都是数字或每个项目都是字母数字,这项功能就可以工作。当我有数字和字母数字的“项”时,它不能正确填充值 代码如下:C# 使用混合数据类型从CSV文件读取数据,c#,asp.net,sql,C#,Asp.net,Sql,只要每个“项目”都是数字或每个项目都是字母数字,这项功能就可以工作。当我有数字和字母数字的“项”时,它不能正确填充值 代码如下: public void updateInventory() { try { if (File.Exists(inventoryUpdateDirectory + "inventoryUpdate.csv")) { csvReader csv = new csvReader();
public void updateInventory()
{
try
{
if (File.Exists(inventoryUpdateDirectory + "inventoryUpdate.csv"))
{
csvReader csv = new csvReader();
DataTable inventory = csv.read(inventoryUpdateDirectory + "inventoryUpdate.csv");
//int test = inventory.Rows.Count;
string sql = "";
foreach (DataRow inventoryItem in inventory.Rows)
{
try
{
sql = " Update Inventory set OnHand = " + inventoryItem[1] + " WHERE Sku = '" + inventoryItem[0].ToString().Trim() + "'";
//executeSQL(sql);
}
catch { }
}
File.Delete(inventoryUpdateDirectory + "inventoryUpdate.csv");
}
else
{
writeToFile("fileDoesntExist", inventoryUpdateDirectory + "error.txt");
}
}
catch { }
}
下面是它读取的文件:
ALB001,0
ALB002,66
10001,0
10016,348
这将有助于:
ALB001,0
ALB002,66
10001,0
10016,348
这将有助于:
ALB001,0
ALB002,66
10001,0
10016,348
这是行不通的:
ALB001,0
ALB002,66
10001,0
10016,348
它将inventoryItem
数组填充为空{}
+ inventoryItem[0] {} object {System.DBNull}
其值应为ALB001
CSV中的第一个“列”应始终视为字符串,因为它可以包含字母数,第二个“列”始终为数字
有人能帮我弄清楚吗
我想我只需要编辑sql查询,将它们转换为字符串,但我不确定
CSV阅读器编辑:
namespace CSV
{
public class csvReader
{
public DataTable read(string strFileName)
{
OleDbConnection conn = new OleDbConnection("Provider=Microsoft.Jet.OleDb.4.0; Data Source = " + System.IO.Path.GetDirectoryName(strFileName) + "; Extended Properties = \"Text;HDR=NO;FMT=Delimited\"");
conn.Open();
string strQuery = "SELECT * FROM [" + System.IO.Path.GetFileName(strFileName) + "]";
OleDbDataAdapter adapter = new OleDbDataAdapter(strQuery, conn);
DataSet ds = new DataSet("CSV File");
adapter.Fill(ds);
return ds.Tables[0];
}
public DataTable read(string strFileName, bool firstRowHeaders)
{
string hdr = "NO";
if (firstRowHeaders) { hdr = "YES"; }
OleDbConnection conn = new OleDbConnection("Provider=Microsoft.Jet.OleDb.4.0; Data Source = " + System.IO.Path.GetDirectoryName(strFileName) + "; Extended Properties = \"Text;HDR=" + hdr + ";FMT=Delimited\"");
conn.Open();
string strQuery = "SELECT * FROM [" + System.IO.Path.GetFileName(strFileName) + "]";
OleDbDataAdapter adapter = new OleDbDataAdapter(strQuery, conn);
DataSet ds = new DataSet("CSV File");
adapter.Fill(ds);
return ds.Tables[0];
}
}
}
在下面的示例中,我在现有值周围添加了单引号,以告诉SQL它应该始终使用字符串。您最好将SQL语句更改为使用“@Parameters”并内联赋值
sql = " Update Inventory set OnHand = '" + inventoryItem[1] + "' WHERE Sku = '" + inventoryItem[0].ToString().Trim() + "'";
问题显然出在CsvReader类中。因为你没有附上它的源代码,所以很难知道为什么它没有用内容填充数据表,我能做的就是猜测 我将尝试通过建议您使用codeproject中的csv阅读器来帮助您: 您不需要使用数据表,因为它使您能够使用简单的while循环对文件行进行迭代。您的代码如下所示:
using (CsvReader reader = new CsvReader(FilePath, Encoding.Default))
{
while (reader.ReadNextRecord())
{
sql = " Update Inventory set OnHand = " + reader.Fields[1] + " WHERE Sku = '" + reader.Fields[0] + "'";
}
}
您可以使用LINQ读取CSV
var data = (from line in File.ReadAllLines(fileName).AsParallel()
select line.Split(',')).ToList();
然后进行适当的铸造、更新。我知道这是一个较老的问题,我已经尝试了许多方法来解决类似的问题,所以我想我会提供我的解决方案。即使我使用的是C#,您也可以继承VB库,TextFieldParser库可以很好地处理这一点。对于我的数据,我不知道将导入多少列,尽管每行的列数相同。某些列包含逗号,但未被引号“”包围。我首先创建了一个DataTable,将所有列转换为字符串,稍后将在其中验证类型。我还删除了文件的头行,我首先使用它创建DataTable。我希望这能帮助别人 我正在使用的数据示例: 校长1,校长2,校长3
A,123,A
B,123,A
C,A,一些数据,然后 更多数据
这是我最终提出的解决方案,效果很好
using Microsoft.VisualBasic.FileIO;
private static DataTable GetDataTableFromCsv(string path)
{
var dataTable = new DataTable("ImportData");
var rows = File.ReadAllLines(path);
var columns = rows[0].Split(',');
foreach (var column in columns)
{
dataTable.Columns.Add(new DataColumn(column.Trim(), typeof(string)));
}
using (var parser = new TextFieldParser(path))
{
parser.Delimiters = new[] { "," };
while (true)
{
var parts = parser.ReadFields();
dataTable.Rows.Add(parts);
if (parser.EndOfData) break;
}
}
dataTable.Rows[0].Delete();
return dataTable;
}
不要使用内联SQL,使用参数并定义您的数据类型。这是由另一位不再在这里的开发人员完成的,目前不允许重写。什么是csvReader?几乎可以肯定问题是从这里开始的。它失败了,因为它看到的第一个值“OnHand”将由它看到的第一个值字符串暗示,但几行之后您将其更改为int。最好是用“”包装该值,告诉SQL它总是得到一个隐藏SQL注入文件的字符串。如果不能完全控制输入,请始终使用参数。空的catch块比没有try/catch更糟糕。这并没有解决它。不管怎么说,手头的总是一个数字。Sku(具有单个刻度)可以是数字或字母数字。我希望这可以解决它,但和以前一样=(好吧,根据你发布的代码,你对如何生成CSV没有太多控制权。我强烈建议用我在回答中建议的CsvReader替换CsvReader。它可靠、非常快速,最重要的是,它让你完全控制如何读取CSV文件。我强烈建议你像其他人一样,不要使用显式SQL查询,但要使用参数。您的应用程序高度暴露于SQL注入。我完全同意您的看法,如果我可以重新编写此内容,我会(我使用的所有内容都有using语句、参数等)。我只需要听上面的人说。我将查看您发布的示例,看看是否可以快速完成此操作。:)我下载了这个,并把它扔进了现有的项目中,使用了上面的例子,效果非常好。非常感谢。这是否需要我花费大量时间重新编写现有代码来处理这个新对象?我只是在寻找最简单的解决方案,使现有的代码基础工作。我仍然是asp.net的不速之客,这让我在重写现有内容时不寒而栗。使用逗号拆分不符合csv规范。例如,如果第一列的值本身包含逗号,那么它将生成包含3列而不是2列的结果。但是,通过调用“安全拆分”行而不是行的方法,它可以很容易地转换为csv投诉代码。拆分调用我可以看到,这将花费您几分钟的时间,因为您有一个列表来填充您的数据表。而且它会更干净。@KobyMizrahy我认为读取结构良好的CSV数据没有问题。您还可以将“跳过”(1)添加到跳过列标题。ReadAllLines返回一个字符串数组。每个字符串包含文件的一行。ReadAllText返回一个包含文件所有行的字符串,结果字符串不包含终止回车符和/或换行符。@plurby-我想强调的是,使用逗号分割csv数据不符合csv规范。例如,如果要保存值“我是一个包含逗号的字符串”,则将使用双引号保存该值。csv阅读器应该显式处理这种情况,否则会导致上面的字符串被拆分为两个不同的列,这是不需要的。帮助我。谢谢