C#net快速导入excel sql oledb 第一行 orcale比对

本文实现在c#中可高效的将excel数据导入到sqlserver数据库中,通过循环来拼接sql,这样做不但容易出错而且效率低下,最好的办法是使用bcp,也就是System.Data.SqlClient.SqlBulkCopy 类来实现。不但速度快,而且代码简单,下面测试代码导入一个6万多条数据的sheet,

using System; 
using System.Data; 
using System.Windows.Forms; 
using System.Data.OleDb; 
namespace WindowsApplication2 

public partial class Form1 : Form 

public Form1() 

InitializeComponent(); 


private void button1_Click(object sender, EventArgs e) 

//测试,将excel中的sheet1导入到sqlserver中 
string connString = "server=localhost;uid=sa;pwd=sqlgis;database=master"; 
System.Windows.Forms.OpenFileDialog fd = new OpenFileDialog(); 
if (fd.ShowDialog() == DialogResult.OK) 

TransferData(fd.FileName, "sheet1", connString); 



public void TransferData(string excelFile, string sheetName, string connectionString) 

DataSet ds = new DataSet(); 
try

//获取全部数据 
string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + excelFile + ";" + "Extended Properties=Excel 8.0;"; 
OleDbConnection conn = new OleDbConnection(strConn); 
conn.Open(); 
string strExcel = ""; 
OleDbDataAdapter myCommand = null; 
strExcel = string.Format("select * from [{0}$]", sheetName); 
myCommand = new OleDbDataAdapter(strExcel, strConn); 
myCommand.Fill(ds, sheetName); 

//如果目标表不存在则创建 
string strSql = string.Format("if object_id('{0}') is null create table {0}(", sheetName); 
foreach (System.Data.DataColumn c in ds.Tables[0].Columns) 

strSql += string.Format("[{0}] varchar(255),", c.ColumnName); 

strSql = strSql.Trim(',') + ")"; 

using (System.Data.SqlClient.SqlConnection sqlconn = new System.Data.SqlClient.SqlConnection(connectionString)) 

sqlconn.Open(); 
System.Data.SqlClient.SqlCommand command = sqlconn.CreateCommand(); 
command.CommandText = strSql; 
command.ExecuteNonQuery(); 
sqlconn.Close(); 

//用bcp导入数据 
using (System.Data.SqlClient.SqlBulkCopy bcp = new System.Data.SqlClient.SqlBulkCopy(connectionString)) 

bcp.SqlRowsCopied += new System.Data.SqlClient.SqlRowsCopiedEventHandler(bcp_SqlRowsCopied); 
bcp.BatchSize = 100;//每次传输的行数 
bcp.NotifyAfter = 100;//进度提示的行数 
bcp.DestinationTableName = sheetName;//目标表 
bcp.WriteToServer(ds.Tables[0]); 


catch (Exception ex) 

System.Windows.Forms.MessageBox.Show(ex.Message); 
}


//进度显示 
void bcp_SqlRowsCopied(object sender, System.Data.SqlClient.SqlRowsCopiedEventArgs e) 

this.Text = e.RowsCopied.ToString(); 
this.Update(); 
}

}

上面的TransferData基本可以直接使用,如果要考虑周全的话,可以用oledb来获取excel的表结构,并且加入ColumnMappings来设置对照字段,这样效果就完全可以做到和sqlserver的dts相同的效果
===================================================================

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.OleDb;
using System.Configuration;
using System.Data.SqlClient;

namespace InExcelOutExcel
{
public partial class ExcelToDB : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
FileSvr fileSvr = new FileSvr();
System.Data.DataTable dt = fileSvr.GetExcelDatatable("C:\\Users\\NewSpring\\Desktop\\Demo\\InExcelOutExcel\\InExcelOutExcel\\excel\\ExcelToDB.xlsx", "mapTable");
fileSvr.InsetData(dt);
}
}
class FileSvr
{
///


/// Excel数据导入Datable
///

///
///
///
public System.Data.DataTable GetExcelDatatable(string fileUrl, string table)
{
//office2007之前 仅支持.xls
//const string cmdText = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties='Excel 8.0;IMEX=1';";
//支持.xls和.xlsx,即包括office2010等版本的 HDR=Yes代表第一行是标题,不是数据;
const string cmdText = "Provider=Microsoft.Ace.OleDb.12.0;Data Source={0};Extended Properties='Excel 12.0; HDR=Yes; IMEX=1'";

System.Data.DataTable dt = null;
//建立连接
OleDbConnection conn = new OleDbConnection(string.Format(cmdText, fileUrl));
try
{
//打开连接
if (conn.State == ConnectionState.Broken || conn.State == ConnectionState.Closed)
{
conn.Open();
}


System.Data.DataTable schemaTable = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);

//获取Excel的第一个Sheet名称
string sheetName = schemaTable.Rows[0]["TABLE_NAME"].ToString().Trim();

//查询sheet中的数据
string strSql = "select * from [" + sheetName + "]";
OleDbDataAdapter da = new OleDbDataAdapter(strSql, conn);
DataSet ds = new DataSet();
da.Fill(ds, table);
dt = ds.Tables[0];

return dt;
}
catch (Exception exc)
{
throw exc;
}
finally
{
conn.Close();
conn.Dispose();
}

}

///


/// 从System.Data.DataTable导入数据到数据库
///

///
///
public int InsetData(System.Data.DataTable dt)
{
int i = 0;
string lng = "";
string lat = "";
string offsetLNG = "";
string offsetLAT = "";

foreach (DataRow dr in dt.Rows)
{
lng = dr["LNG"].ToString().Trim();
lat = dr["LAT"].ToString().Trim();
offsetLNG = dr["OFFSET_LNG"].ToString().Trim();
offsetLAT = dr["OFFSET_LAT"].ToString().Trim();

//sw = string.IsNullOrEmpty(sw) ? "null" : sw;
//kr = string.IsNullOrEmpty(kr) ? "null" : kr;

string strSql = string.Format("Insert into DBToExcel (LNG,LAT,OFFSET_LNG,OFFSET_LAT) Values ('{0}','{1}',{2},{3})", lng, lat, offsetLNG, offsetLAT);

string strConnection = ConfigurationManager.ConnectionStrings["ConnectionStr"].ToString();
SqlConnection sqlConnection = new SqlConnection(strConnection);
try
{
// SqlConnection sqlConnection = new SqlConnection(strConnection);
sqlConnection.Open();
SqlCommand sqlCmd = new SqlCommand();
sqlCmd.CommandText = strSql;
sqlCmd.Connection = sqlConnection;
SqlDataReader sqlDataReader = sqlCmd.ExecuteReader();
i++;
sqlDataReader.Close();
}
catch (Exception ex)
{
throw ex;
}
finally
{
sqlConnection.Close();

}
//if (opdb.ExcSQL(strSql))
// i++;
}
return i;
}
}
}

C#net快速导入excel sql oledb 第一行 orcale比对_第1张图片

假设有两个表A,B,都只有一个字段PHONE

1,MINUS

SELECT PHONE FROM A MINUS SELECT PHONE FROM B; 相当于用结果集A减去结果B得出的结果集。同样的效果也可以用SELECT PHONE FROM A WHERE NOT EXISTS(SELECT 1 FROM B WHERE A.PHOEN=B.PHONE)来达到。

2,INTERSECT

SELECT PHONE FROM A INTERSECT SELECT PHONE FROM B; 相当于求结果集A与结果集B的交集。

3,UNION

SELECT PHONE FROM A UNION SELECT PHONE FROM B; 相当于求结果集A与结果集B的合集,去重。

4,UNION ALL

SELECT PHONE FROM A UNION ALL SELECT PHONE FROM B; 相当于求结果集A与结果集B的合集,不去重。

3 实例演练

3.1创建表并插入数据

Create table A(A1 number(12),A2 varchar2(50));
Create table B(B1 number(12),B2 varchar2(50));
Insert Into A Values (1,'a');
Insert Into A Values (2,'ba');
Insert Into A Values (3,'ca');
Insert Into A Values (4,'da');
Insert Into B Values (1,'a');
Insert Into B Values (2,'bba');
Insert Into B Values (3,'ca');
Insert Into B Values (5,'dda');
Insert Into B Values (6,'Eda');
COMMIT;

3.2进行增量差异数据比较

3.2.1原始表A与比较表B的增量差异

Select * from A minus select * from B;

结果如下:

A1 A2
---------------------------------------------------------------
2 ba
4 da

3.2.2比较表B与原始表A的增量差异

Select * from B minus select * from A;

结果如下:

B1 B2
---------------------------------------------------------------
2 bba
5 dda
6 Eda

3.2.3两种增量差异的合集

此合集包含3类数据:

--1、原始表A存在、比较表B不存在,属于删除类数据,出现次数1

--2、原始表A不存在、比较表B存在,属于新增类数据,出现次数1

--3、原始表A和比较表B都存在,属于修改类数据,出现次数2

Select A1,A2,1 t from (Select * from A minus select * from B) union
Select B1,B2,2 t from (Select * from B minus select * from A);

结果如下:

A1 A2 T
------------- -------------------------------------------------- ----------
2 ba 1
2 bba 2
4 da 1
5 dda 2
6 Eda 2

3.3得到结果

Select A1,sum(t) from
(Select A1,A2,1 t from (Select * from A minus select * from B) union
Select B1,B2,2 t from (Select * from B minus select * from A))
Group by A1;

结果如下:

A1 SUM(T)
-----------------------
6 2
2 3
4 1
5 2

结果中SUM(T)为1的为“删除”的数据,SUM(T)为2的为“新增”的数据,SUM(T)为3的为“修改”的数据。

方法二(通过Sql语句来比较):

  创建表的语句:

create table formula(
  id varchar2(50) primary key--自动生成的,唯一的。
  formulaName varchar2(50),
  formulaContent varchar2(2000),
  formulaType varchar2(20),
  )

  当中除id不为空,其它三项均可能为空。

  一般情况下我们可以用

select * from formula A where not exists (select * from formula B where A.formulaName=
  B.formulaName and A.formulaContent=B.formulaContent and A.formulaType=B.formulaType)

  在oracle 情况下如果两张表的某个字段都为null则其通过A.*=B.*是比较不出来的。

  因此要额外加上这样的判断

or(A.formulaContent is null and B.formulaContent is null) or
  (A.fomrulaName is null and B.fomrulaName is null) or (A.formulaType is null and B.fomrulaType is null)

  通过上面这个sql语句我们就可以找在A表中存在,但在B表中不存在的数据

  反过来可以查询在B表中存在,但在A表中不存在的数据。

  若两个查询都为空,则说明两张表的相应字段完全相同。

  若这两张表在不同的数据库,则要通过建立DBLink。

  优点:数据比较快,特别是在数据量比较大的数据优势更加明显,

  缺点:比较时不能很快看出两张表的差异。因为查询的只是当中的某一张表。


select * from A minus select * from B;
  select * from B minus select * from A;
比较表结构相同的两表之间的差异用minus。 不同的字段可以选择对应的列来比较 如 select pno,cno from A minus select pno,cno from B;  insert into i_itembom select bb.* from ( select item_code,mat_code from i_itembom_bak minus select item_code,mat_code from i_itembom) aa inner join i_itembom_bak bb on aa.item_code=bb.item_code and aa.mat_code=BB.MAT_CODE 
insert into i_itembom   select bb.item_code,bb.mat_code,bb.qty_perunit,location,'','ERP',SYSDATE,bb.STATUS_MOD from (select item_code,mat_code from I_ERP_ITEM_BOM minus select item_code,mat_code from i_itembom) aa inner join I_ERP_ITEM_BOM bb on aa.item_code=bb.item_code and aa.mat_code=BB.MAT_CODE


你可能感兴趣的:(net,C#,asp.net,sql)