1

只要每个“项目”都是数字或每个项目都是字母数字,这就有效。当我有数字和字母数字的“项目”时,它不会正确填写值。

这是代码:

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 阅读器编辑:

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

4 回答 4

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] + "'";
   }
} 
于 2012-05-03T21:43:30.727 回答
1

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

我正在使用的数据示例:

Header1,Header2,Header3
A,123,A
B,123,A
C,A,Somedata,然后是更多数据

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

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;
        }
于 2014-03-14T14:46:35.643 回答
0

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

sql = " Update Inventory set OnHand = '" + inventoryItem[1] + "' WHERE Sku = '" + inventoryItem[0].ToString().Trim() + "'";
于 2012-05-03T21:36:58.073 回答
0

您可以使用 LINQ 读取 CSV

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

然后进行适当的铸造,更新。

于 2012-05-03T21:46:02.397 回答