【发布时间】:2020-05-07 20:06:57
【问题描述】:
我有一个 Excel 文件,其工作表名称与 SQL 表名称相同,但列映射失败,因为两者具有相同的列但列的顺序不同,请帮助我。
【问题讨论】:
标签: c# .net sql-server
我有一个 Excel 文件,其工作表名称与 SQL 表名称相同,但列映射失败,因为两者具有相同的列但列的顺序不同,请帮助我。
【问题讨论】:
标签: c# .net sql-server
已编辑:最后添加了另一个示例。
实现您所要求的许多方法之一是将工作表作为数据表导入 c#,然后使用 SqlBulkCopy (SqlBulkCopy (MSDN)) 插入数据。这种方法更适合大文件,因为 SqlBulkCopy 使用批量插入命令。
对于第一步(将文件导入为数据表),您有许多选项,例如使用 OLEDB 用于 xls 或 xlsx(您可以使用我的示例或其他示例,例如 this link 或 this),使用第三方库,例如作为easyxls。
using System;
using System.Drawing;
using System.Windows.Forms;
using Excel = Microsoft.Office.Interop.Excel;
namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
try
{
System.Data.OleDb.OleDbConnection MyConnection ;
System.Data.DataSet DtSet ;
System.Data.OleDb.OleDbDataAdapter MyCommand ;
MyConnection = new System.Data.OleDb.OleDbConnection("provider=Microsoft.Jet.OLEDB.4.0;Data Source='c:\\csharp.net-informations.xls';Extended Properties=Excel 8.0;");
MyCommand = new System.Data.OleDb.OleDbDataAdapter("select * from [Sheet1$]", MyConnection);
MyCommand.TableMappings.Add("Table", "TestTable");
DtSet = new System.Data.DataSet();
MyCommand.Fill(DtSet);
dataGridView1.DataSource = DtSet.Tables[0];
MyConnection.Close();
}
catch (Exception ex)
{
MessageBox.Show (ex.ToString());
}
}
}
}
在第二步之后,您可以使用带有列映射的 SQLBulkCopy 将 dataTable 列映射到您的数据库表列。
using System.Data.SqlClient;
class Program
{
static void Main()
{
string connectionString = GetConnectionString();
// Open a sourceConnection to the AdventureWorks database.
using (SqlConnection sourceConnection =
new SqlConnection(connectionString))
{
sourceConnection.Open();
// Perform an initial count on the destination table.
SqlCommand commandRowCount = new SqlCommand(
"SELECT COUNT(*) FROM " +
"dbo.BulkCopyDemoDifferentColumns;",
sourceConnection);
long countStart = System.Convert.ToInt32(
commandRowCount.ExecuteScalar());
Console.WriteLine("Starting row count = {0}", countStart);
// Get data from the source table as a SqlDataReader.
SqlCommand commandSourceData = new SqlCommand(
"SELECT ProductID, Name, " +
"ProductNumber " +
"FROM Production.Product;", sourceConnection);
SqlDataReader reader =
commandSourceData.ExecuteReader();
// Set up the bulk copy object.
using (SqlBulkCopy bulkCopy =
new SqlBulkCopy(connectionString))
{
bulkCopy.DestinationTableName =
"dbo.BulkCopyDemoDifferentColumns";
// Set up the column mappings by name.
SqlBulkCopyColumnMapping mapID =
new SqlBulkCopyColumnMapping("ProductID", "ProdID");
bulkCopy.ColumnMappings.Add(mapID);
SqlBulkCopyColumnMapping mapName =
new SqlBulkCopyColumnMapping("Name", "ProdName");
bulkCopy.ColumnMappings.Add(mapName);
SqlBulkCopyColumnMapping mapMumber =
new SqlBulkCopyColumnMapping("ProductNumber", "ProdNum");
bulkCopy.ColumnMappings.Add(mapMumber);
// Write from the source to the destination.
try
{
bulkCopy.WriteToServer(reader);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
// Close the SqlDataReader. The SqlBulkCopy
// object is automatically closed at the end
// of the using block.
reader.Close();
}
}
// Perform a final count on the destination
// table to see how many rows were added.
long countEnd = System.Convert.ToInt32(
commandRowCount.ExecuteScalar());
Console.WriteLine("Ending row count = {0}", countEnd);
Console.WriteLine("{0} rows were added.", countEnd - countStart);
Console.WriteLine("Press Enter to finish.");
Console.ReadLine();
}
}
private static string GetConnectionString()
// To avoid storing the sourceConnection string in your code,
// you can retrieve it from a configuration file.
{
return "Data Source=(local); " +
" Integrated Security=true;" +
"Initial Catalog=AdventureWorks;";
}
}
SqlBulkCopy 用法的另一个例子:
public bool CopyTransactionDataToTable(DataTable Dt, long ProductID)
{
try
{
SqlBulkCopy copy = new SqlBulkCopy(Adapter.GetActiveConnection().ConnectionString);
Collection = mapping.LoadMappedNameEntityByProductID(ProductID);
copy.ColumnMappings.Add("ProductID", "ProductID");
copy.ColumnMappings.Add("ResellerID", "ResellerID");
copy.ColumnMappings.Add("Status", "Status");
copy.ColumnMappings.Add("PK_ID", "TxID");
copy.DestinationTableName = "TBLProdect";
copy.BulkCopyTimeout = ConfigurationSettings.AppSettings.Get(UIConstants.SQLTimeOut).ToInt32();
copy.WriteToServer(Dt);
Adapter.CommandTimeOut = copy.BulkCopyTimeout;
return true;
}
catch (Exception ex)
{
Log.Error(ex);
return false;
}
}
【讨论】:
您没有说明您是否希望重复或编程等 - 但其他两个选项是使用 SQL Server 数据导入/导出向导
https://msdn.microsoft.com/en-us/library/ms141209.aspx
另一种选择是使用 SQL Server Integration Services (SSIS)
http://www.sqlshack.com/using-ssis-packages-import-ms-excel-data-database/
【讨论】: