【问题标题】:Import a CSV file to SQL Server using SqlBulkCopy使用 SqlBulkCopy 将 CSV 文件导入 SQL Server
【发布时间】:2016-11-17 20:14:46
【问题描述】:

我有这个函数可以创建一个表,然后接收一个 CSV 文件。我需要一个 ID 列,它会自动递增,以供以后使用。因此,我使用 ID 字段运行了以下查询。在它不起作用之前,因为最初 CSV 文件没有 ID 列,所以当它被发送到数据库时会出现错误。所以我的下一个想法是在 CSV 文件中添加一个没有值的空白 ID 列,然后再次尝试查询。还是有问题。我的 c# 代码中的错误是:“从 bcp 客户端接收到 colid 1 的无效列长度。”我猜是 ID 列。有没有办法同时插入这个 ID 列并自动递增?

private void button2_Click(object sender, EventArgs e)
    {
        string connectionString = "Data Source=LPMSW09000012JD\\SQLEXPRESS;Initial Catalog=Pharmacies;Integrated Security=True";
        string query = "CREATE TABLE [dbo].[" + textBox1.Text + "](" +"ID int IDENTITY (1,1) PRIMARY KEY," + "[Code] [varchar] (13) NOT NULL," +
       "[Description] [varchar] (50) NOT NULL," + "[NDC] [varchar] (50) NULL," +
        "[Supplier Code] [varchar] (38) NULL," + "[UOM] [varchar] (8) NULL," + "[Size] [varchar] (8) NULL,)";


        using (SqlConnection connection = new SqlConnection(connectionString))
        {
            SqlCommand command = new SqlCommand(query, connection);
            command.Connection.Open();
            command.ExecuteNonQuery();
        }

        SqlConnection con = new SqlConnection("Data Source=LPMSW09000012JD\\SQLEXPRESS;Initial Catalog=Pharmacies;Integrated Security=True");
        string filepath = textBox2.Text; //"C:\\Users\\jdavis\\Desktop\\CRF_105402_New Port Maria Rx.csv";
        StreamReader sr = new StreamReader(filepath);
        string line = sr.ReadLine();
        string[] value = line.Split(',');
        DataTable dt = new DataTable();
        DataRow row;
        foreach (string dc in value)
        {
            dt.Columns.Add(new DataColumn(dc));
        }

        while (!sr.EndOfStream)
        {
            value = sr.ReadLine().Split(',');
            if (value.Length == dt.Columns.Count)
            {
                row = dt.NewRow();
                row.ItemArray = value;
                dt.Rows.Add(row);
            }
        }
        SqlBulkCopy bc = new SqlBulkCopy(con.ConnectionString, SqlBulkCopyOptions.TableLock);
        bc.DestinationTableName = textBox1.Text;
        bc.BatchSize = dt.Rows.Count;
        con.Open();
        bc.WriteToServer(dt);
        bc.Close();
        con.Close();

    }

【问题讨论】:

  • id 列应该是为您自动创建的,并且您没有在其中插入任何内容。当您尝试执行第一步时,究竟是什么代码不起作用 - 专注于那个 - 应该可以正常工作。
  • 同样的事情Received an invalid column length from the bcp client for colid 1.
  • 此链接可能会有所帮助:stackoverflow.com/questions/6651809/… 使用普通插入,您根本不需要将自动标识列添加到 DataTable - 除非您指出,否则数据库不需要它想要提供明确的值。
  • 我需要它,如果输入重复项,它将用作唯一标识符,我需要删除它(从我的 c# 应用程序中删除它。那个链接没有解决我想要的问题,因为他的问题是 SQLBulk 复制选项被设置为保持身份。@JohnD
  • 我有点困惑——你想提供你自己的自动增量数字,还是你想让数据库为你生成它们?如果您希望数据库为您生成它们,请不要提及 DataTable 中的列 - 数据库不希望看到它,因为它承担了生成自动递增数字的责任。

标签: c# .net sql-server winforms ado.net


【解决方案1】:

我想您在 SQL Server 中有一个您以这种方式创建的表:

CREATE TABLE [dbo].[Table1] (
    [Column1]   INT           IDENTITY (1, 1) NOT NULL,
    [Column2]   NVARCHAR (50) NOT NULL
);

包含这些值的文件:

Column1,Column2
1,N1
2,N2
3,N3

所以要将值批量插入到表中,您可以这样使用SqlBulkCopy

var lines = System.IO.File.ReadAllLines(@"d:\data.txt");
if (lines.Count() == 0) return;
var columns = lines[0].Split(',');
var table = new DataTable();
foreach (var c in columns)
    table.Columns.Add(c);

for (int i = 1; i < lines.Count() - 1; i++)
    table.Rows.Add(lines[i].Split(','));

var connection = @"your connection string";
var sqlBulk = new SqlBulkCopy(connection);
sqlBulk.DestinationTableName = "Table1";
sqlBulk.WriteToServer(table);

【讨论】:

  • 附带说明:1) 发布问题时,请考虑发布Minimal, Complete, and Verifiable example。只需将我的答案与您的问题进行比较,看看您如何编写其他人可以简单使用的代码。 2) 代码格式化非常重要,因此请始终尝试格式化代码并使其尽可能可读。 我希望这些提示可以帮助您更好地使用该网站:)
  • 非常好的答案。
猜你喜欢
  • 2017-02-15
  • 2018-10-19
  • 2013-02-20
  • 2020-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多