使用混合数据类型从CSV文件中读取数据

时间:2012-05-03 21:20:59

标签: c# asp.net sql

只要每个'项目都有效。是数字或每个项目都是字母数字。当我有'项目'这是数字和字母数字,它没有正确填写值。

以下是代码:

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

它将inventoryItem数组填充为空{}

+       inventoryItem[0]    {}  object {System.DBNull}

哪个值应为ALB001

第一栏'在CSV中应该始终被视为一个字符串,因为它可以包含多个字母,第二个列是'将永远是数字。

任何人都能帮我解决这个问题吗?

我想我只需编辑sql查询将它们转换为字符串,但我不确定。

CSV READER EDIT:

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];
        }
    }
}

4 个答案:

答案 0 :(得分:1)

问题显然在CsvReader类中。由于您没有附加其源代码,因此很难知道为什么它没有用内容填充数据表,我能做的最好就是猜测。

我会建议您使用codeproject中的csv阅读器来帮助您: http://www.codeproject.com/Articles/86973/C-CSV-Reader-and-Writer

您不需要使用数据表,因为它允许您使用简单的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] + "'";
   }
} 

答案 1 :(得分:1)

我知道这是一个较老的问题,我已经尝试了许多方法来解决类似的问题所以我想我会提供我的解决方案。即使我使用C#,您也可以继承VB库,而TextFieldParser库可以很好地处理它。对于我的数据,我不知道将导入多少列,尽管每行的列数相同。有些列包含逗号但未被引号括起来""。我创建了一个DataTable,首先将所有列转换为字符串,稍后我将验证类型。我还删除了首先用于创建DataTable的文件所具有的标题行。我希望这可以帮助别人。

我正在使用的数据示例:

  

Header1,Header2,Header3
A,123,A
B,123,A
C,A,Somedata,then   更多数据

这是我最终提出的解决方案,效果很好。

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;
        }

答案 2 :(得分:0)

在下面的示例中,我在OnHand值周围添加了单引号,告诉SQL它应该总是期望一个字符串。您最好更改SQL语句以使用“@Parameters”并将值分配为内联。

sql = " Update Inventory set OnHand = '" + inventoryItem[1] + "' WHERE Sku = '" + inventoryItem[0].ToString().Trim() + "'";

答案 3 :(得分:0)

您可以使用LINQ

读取CSV
var data = (from line in File.ReadAllLines(fileName).AsParallel()
            select line.Split(',')).ToList();

然后进行适当的施法,更新。