0

我正在尝试使用 OleDb 从 datagridview 将 Excel 工作表插入 SQL Server 数据库。

我使用的代码:

namespace importfromexcel
{
  public partial class Form1 : Form
  {
     SqlConnection conn = new SqlConnection("Data Source=HAMNDOSH-PC\\SQLEXPRESS;Initial    Catalog=mohammed;Integrated Security=True");
  //  SqlCommand cmd;

     public Form1()
     {
        InitializeComponent();
     }

     OpenFileDialog ofd = new OpenFileDialog();

     private void button2_Click(object sender, EventArgs e)
     {
        if (ofd.ShowDialog() == DialogResult.OK)
        {
            textBox1.Text = ofd.FileName;
        }
    }

    private void button1_Click(object sender, EventArgs e)
    {
        string excelConnectionString = @"Provider=Microsoft.Jet.OLEDB.4.0;data source=" + ofd.FileName + @";Extended Properties=Excel 8.0;";
        // Create Connection to Excel Workbook

        //We can Import excel to sql server like this
        using (OleDbConnection connection = new OleDbConnection(excelConnectionString))
        {
            OleDbCommand command = new OleDbCommand("Select fname,lname FROM [sheet1$]", connection);

            connection.Open();

            // Create DbDataReader to Data Worksheet 
            using (DbDataReader dr = command.ExecuteReader())
            {
                // SQL Server Connection String 
                string sqlConnectionString = "Data Source=HAMNDOSH-PC\\SQLEXPRESS;Initial Catalog=mohammed;Integrated Security=True";
                //  SqlCommand cmd;

                // Bulk Copy to SQL Server 
                using (SqlBulkCopy bulkCopy = new SqlBulkCopy(sqlConnectionString))
                {
                    bulkCopy.DestinationTableName = "test";
                    bulkCopy.WriteToServer(dr);
                }
            }
        }
    }
  }
}

我的数据库名称是:mohammed表名test有两列firstnamelastnameExcel工作表的列是fnamelname..

问题是,当我执行代码并在单击 button1 时从 button2 插入 Excel 工作表后出现窗口错误

vshot32-clr2.exe 已停止工作

请问有什么帮助吗??

4

3 回答 3

0

在 excel 连接字符串的扩展属性中,您可能希望设置 HDR=YES 和 IMEX=1。HDR=YES 将读取您的 Excel 工作表中的第一行,并读取存储在每个单元格中的数据作为列名。IMEX=1 告诉 JET 插入数据,而不管每个单元格的数据类型如何。

看看我自己写的这段代码,它可能会对你有所帮助。

        //ExcelDA Class
        public ExcelDA()
    {
        connString = @"Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" + ofd.FileName + "; Extended Properties=" + '"' + "Excel 8.0; HDR=Yes; IMEX=1" + '"';
    }

    /// <summary>
    /// Method used to retrieve a datatable from excel sheet
    /// </summary>
    public DataTable GetProductsExcel()
    {
        StringBuilder excBuilder = new StringBuilder();
        excBuilder.Append("SELECT * FROM [Sheet1$];");
        //
        try
        {
            return ExecuteSqlStatement(excBuilder.ToString());
        }
        catch (Exception) 
        { 
            MessageBox.Show("Error retreiving data");
            return null;
        }
    }
    private DataTable ExecuteSqlStatement(string command)
    {
        using (OleDbConnection conn = new OleDbConnection(connString))
        {
            try
            {
                conn.Open();
                using (OleDbDataAdapter adaptor = new OleDbDataAdapter(command, conn))
                {
                    DataTable table = new DataTable();
                    adaptor.Fill(table);
                    return table;
                }
            }
            catch (SqlException e)
            {
                throw e;
            }
        }
    }
    //SqlDA class
    public void ExecuteSQLCommand(string comm)
    {
        try
        {
            using (SqlConnection conn = new SqlConnection(_connectionString))
            {
                conn.Open();

                using (SqlCommand command = new SqlCommand(comm, conn))
                {
                    command.ExecuteNonQuery();
                }
            }
        }
        catch (ArgumentOutOfRangeException ex)
        {
            throw ex;
        }

        catch (ArgumentException ex)
        {
            throw ex;
        }
        catch (SqlException ex) { throw ex; }
    }
    public void AddNames(string fName, string sName)
    {
          StringBuilder sqlQuery = new StringBuilder();
          //build sql insert statement here
          ExecuteSQLCommand(sqlBuilder.ToString());
    }

    //Program class
    ExcelDA reader = new ExcelDA();
    DataTable names = reader.GetSuppliersExcel();
    //string array to store excel row data for names
    string[] arr2 = new string[2] { "", ""};
        //recursive loop to retrieve each row and values from each rows columns
        foreach (DataRow row in suppliers.Rows)
        {
            for (int i = 0; i < names.Columns.Count; i++)
            {
                if (i == (names.Columns.Count - 1))
                {
                    arr2[i] = (row[i].ToString());
                }
                else
                {
                    arr2[i] = (row[i].ToString());
                }
            }
        }

            try
            {
                sql.AddNames(arr2[0], arr2[1]);
                Console.WriteLine("Added Data to SQL");
            }
            catch (Exception) { }
于 2012-12-05T16:09:53.993 回答
0

我不知道这是否是根本原因,但是当不能保证对话框选择了有效文件时,您会ofd.FileName在事件中引用。Click由于您将该值存储在文本框中,因此我将其更改为:

string excelConnectionString = 
    @"Provider=Microsoft.Jet.OLEDB.4.0;data source=" 
          + textBox1.Text 
          + @";Extended Properties=Excel 8.0;";

我还将验证您是否能够在尝试实现批量复制之前查询数据(例如,通过写入文本文件)作为测试。另请注意,源数据必须具有完全相同的结构(包括列顺序),除非您提供ColumnMapping.

于 2012-12-05T15:46:38.960 回答
0

Sql server 有一个名为 Sql Server Data Tools 的导入工具...在那里您可以找到从 excel 文件导入的活动...非常“最终用户”交易,我的意思是您可以通过拖放配置所有内容基础...

于 2012-12-05T15:54:25.117 回答