介绍两种途径将数据从EXCEL中导入到SQL

一、        在程序中,用ADO.NET。代码

 

//连接串
string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Extended Properties=Excel 8.0;Data Source=" + [EXCEL文件,含路径] + ";";
OleDbConnection conn = new OleDbConnection(strConn);
conn.Open();
 
DataTable dtSchema = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables,new object[] {null, null, null, "TABLE"});
DataSet ds = new DataSet();
//一个EXCEL文件可能有多个工作表,遍历之
foreach( DataRow dr in dtSchema.Rows )
{
   string table = dr["TABLE_NAME"].ToString();
   string strExcel = "SELECT * FROM [" + table + "]";
   ds.Tables.Add(table);
 
   OleDbDataAdapter myCommand = new OleDbDataAdapter(strExcel,conn);
   myCommand.Fill(ds,table);
}
 
conn.Close();

 

这样,读取出来的数据就藏在DataSet里了。

采用这种方式,数据库

 

二、        在查询分析器里,直接写SQL语句:

如果是导入数据到现有表,则采用

INSERT INTO 表 SELECT * FROM OPENROWSET('MICROSOFT.JET.OLEDB.4.0'
,'Excel 5.0;HDR=YES;DATABASE=c:/test.xls',sheet1$)
的形式
如果是导入数据并新增表,则采用
SELECT * INTO 表 FROM OPENROWSET('MICROSOFT.JET.OLEDB.4.0'
,'Excel 5.0;HDR=YES;DATABASE=c:/test.xls',sheet1$)
的形式。
 
以上语句是将EXCEL文件里SHEET1工作表中所有的列都读进来,如果只想导部分列,可以
INSERT INTO 表(a1,a2,a3) SELECT a1,a2,a3 FROM OPENROWSET('MICROSOFT.JET.OLEDB.4.0'
,'Excel 5.0;HDR=YES;DATABASE=c:/test.xls',sheet1$)
 
其实可以将OPENROWSET('MICROSOFT.JET.OLEDB.4.0'
,'Excel 5.0;HDR=YES;DATABASE=c:/test.xls',sheet1$)当成一个表,例如我就写过这样一个句子:
 
INSERT INTO eval_channel_employee(channel,employee_id)
SELECT CASE a.渠道 WHEN 'DIY' THEN 1 WHEN 'RDC' THEN 0 WHEN 'KCM' THEN 2 ELSE 3 END
,b.id FROM
OPENROWSET('MICROSOFT.JET.OLEDB.4.0'
,'Excel 5.0;HDR=YES;DATABASE=c:/temp/name.xls',sheet1$) AS a,pers_employee b
WHERE a.员工编码=b.code

 

不管是哪种方式,哪种途径,系统都会默认将第一行上的内容作为字段名。


在做项目时,经常遇到要将Excel中的大量数据导入到Access数据库中,原来的做法是读一条写一条,若导入上万条的数据需要几分仲时间,速度很慢。有没有最快的方法呢?经本人研究、反复的实验,终于写出了最快速的批量导入大批量数据的方法,上万条数据只需几秒钟就可全部导入,够快了吧。代码公布出来与大家分享。



Sql代码


1. Set  conn = Server.CreateObject( "adodb.Connection"
2. connstr =  "Provider=Microsoft.Jet.OLEDB.4.0; Data source="  & Server.MapPath( "test.mdb"
3. conn. Open
4. sql =  "insert into userinfo select userName,userAccount,userStatus from [userinfo$] in '"  & Server.MapPath( "hbwlUserInfo.xls"
5. "' 'Excel 8.0;' where userAccount is not null"
6. 7. conn. Execute  (sql)  


SQL Server 
 8.     
9.           大部分人都知道用oledb来读取数据到dataset,但是读取之后怎么处理dataset就千奇百怪了。很多人通过循环来拼接sql,这样做不但容易出错而且效率低下,System.Data.SqlClient.SqlBulkCopy 对于新手来说还是比较陌生的,这个就是传说中效率极高的bcp,6万多数据从excel导入到sql只需要4.5秒。 
       

 10.          
        
11. using 
12.          System;
13.  
14.         using 
         System.Data;
15.  
16.         using 
         System.Windows.Forms;
17.  
18.         using 
         System.Data.OleDb;
19.  
20.         namespace 
         WindowsApplication2
21.  
22.         
23.  
24.         {
25.       public   partial   class  Form1 : Form
26.       
27.  {
28.           public  Form1()
29.           
30.  {
31.              InitializeComponent();
32.          } 
33. 
34.           private   void  button1_Click( object  sender, EventArgs e)
35.           
36.  {
37.               // 测试,将excel中的sheet1导入到sqlserver中 
38.               string  connString  =   " server=localhost;uid=sa;pwd=sqlgis;database=master " ;
39.              System.Windows.Forms.OpenFileDialog fd  =   new  OpenFileDialog();
40.               if  (fd.ShowDialog()  ==  DialogResult.OK)
41.               
42.  {
43.                  TransferData(fd.FileName,  " sheet1 " , connString);
44.              } 
45.          } 
46. 
47.           public   void  TransferData( string  excelFile,  string  sheetName,  string  connectionString)
48.           
49.  {
50.              DataSet ds  =   new  DataSet();
51.               try 
52.               
53.  {
54.                   // 获取全部数据 
55.                   string  strConn  =   " Provider=Microsoft.Jet.OLEDB.4.0; "   +   " Data Source= "   +  excelFile  +   " ; "   +   " Extended Properties=Excel 8.0; " ;
56.                  OleDbConnection conn  =   new  OleDbConnection(strConn);
57.                  conn.Open();
58.                   string  strExcel  =   "" ;
59.                  OleDbDataAdapter myCommand  =   null ;
60.                  strExcel  =   string .Format( " select * from [{0}$] " , sheetName);
61.                  myCommand  =   new  OleDbDataAdapter(strExcel, strConn);
62.                  myCommand.Fill(ds, sheetName);
63. 
64.                   // 如果目标表不存在则创建 
65.                   string  strSql  =   string .Format( " if object_id('{0}') is null create table {0}( " , sheetName);
66.                   foreach  (System.Data.DataColumn c  in  ds.Tables[ 0 ].Columns)
67.                   
68.  {
69.                      strSql  +=   string .Format( " [{0}] varchar(255), " , c.ColumnName);
70.                  } 
71.                  strSql  =  strSql.Trim( & apos;, & apos;)  +   " ) " ;
72. 
73.                   using  (System.Data.SqlClient.SqlConnection sqlconn  =   new  System.Data.SqlClient.SqlConnection(connectionString))
74.                   
75.  {
76.                      sqlconn.Open();
77.                      System.Data.SqlClient.SqlCommand command  =  sqlconn.CreateCommand();
78.                      command.CommandText  =  strSql;
79.                      command.ExecuteNonQuery();
80.                      sqlconn.Close();
81.                  } 
82.                   // 用bcp导入数据 
83.                   using  (System.Data.SqlClient.SqlBulkCopy bcp  =   new  System.Data.SqlClient.SqlBulkCopy(connectionString))
84.                   
85.  {
86.                      bcp.SqlRowsCopied  +=   new  System.Data.SqlClient.SqlRowsCopiedEventHandler(bcp_SqlRowsCopied);
87.                      bcp.BatchSize  =   100 ; // 每次传输的行数 
88.                      bcp.NotifyAfter  =   100 ; // 进度提示的行数 
89.                      bcp.DestinationTableName  =  sheetName; // 目标表 
90.                      bcp.WriteToServer(ds.Tables[ 0 ]);
91.                  } 
92.              } 
93.               catch  (Exception ex)
94.               
95.  {
96.                  System.Windows.Forms.MessageBox.Show(ex.Message);
97.              } 
98. 
99.          } 
100. 
101.           // 进度显示 
102.           void  bcp_SqlRowsCopied( object  sender, System.Data.SqlClient.SqlRowsCopiedEventArgs e)
103.           
104.  {
105.               this .Text  =  e.RowsCopied.ToString();
106.               this .Update();
107.          } 
108. 
109. 
110.      } 
111.  }
  1.  
  2.  
      上面的TransferData基本可以直接使用,如果要考虑周全的话,可以用oledb来获取excel的表结构,并且加入ColumnMappings来设置对照字段,这样效果就完全可以做到和sqlserver的dts相同的效果了。