2014年8月2日 星期六

[ASP.NET]SqlBulkCopy 大量的資料庫輸入

因上次介紹了 Excel 匯入的方法,所以這一次也來介紹一個相關聯的大量資料庫寫入方法。

Excel 匯入方法
[ASP.NET]讀取 Excel 的方式 - 使用 NPOI 方式
[ASP.NET]讀取 Excel 的方式 - 使用 Excel模組 方式

就目前所知的資料庫寫入伺服器的方法有兩種

  • 使用 AddWithValue 的方法寫入
    • 宣告 資料庫連結SqlConnection 與 資料庫指令SqlCommand
    • SqlCommand 下新增指令 ( Insert into ... values ... )
    • 設定參數 SqlParameter 不設定的話會有 Sql injection 的問題
    • 如果是要寫入多筆資料的話,就是使用 for 一筆一筆的輸入
    • 但是只要有資料輸入出錯的話 (資料欄位型別出錯之類的) 上一筆輸入成功的資料還是會寫入,就會變成輸入成功的寫進資料庫了,但是到出錯那個地方就斷了的窘境。
  • 使用 SqlBulkCopy 的方法寫入
    • 宣告 資料庫連結SqlConnection
    • 寫入的方法通常是把想要寫入的資料放到 DataTable
    • 輸入要寫入的 資料表
    • 對照 資料庫欄位 與 DataTable的欄位
    • 最後使用 WriteToServer(DataTable) 寫入資料庫即可

HTML:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="SqlBulkCopy.WebForm1" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    
        <asp:Button ID="btn100" runat="server" onclick="btn100_Click" Text="輸入百個隨機資料" />
        <br />
    
    </div>
    </form>
</body>
</html>
asp.cs:

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Linq;
   4:  using System.Web;
   5:  using System.Web.UI;
   6:  using System.Web.UI.WebControls;
   7:   
   8:  // 使用 DataTable
   9:  using System.Data;
  10:  // 使用 Sql連結與指令
  11:  using System.Data.SqlClient;
  12:   
  13:   
  14:   
  15:  namespace SqlBulkCopy
  16:  {
  17:      public partial class WebForm1 : System.Web.UI.Page
  18:      {
  19:          protected void Page_Load(object sender, EventArgs e)
  20:          {
  21:   
  22:          }
  23:   
  24:          protected void btn100_Click(object sender, EventArgs e)
  25:          {
  26:              // 設定資料庫連結
  27:              SqlConnection conn = new SqlConnection(System.Web.Configuration.WebConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
  28:              // 建立 DataTable
  29:              DataTable dt = new DataTable();
  30:              // 加入欄位
  31:              dt.Columns.Add("Num1");
  32:              dt.Columns.Add("Num2");
  33:              dt.Columns.Add("Num3");
  34:   
  35:              // 隨機輸入值到 DataTable
  36:              // 欄位迴圈值
  37:              for (int row = 0; row < 100; row++) 
  38:              {
  39:                  // 建立 DataRow
  40:                  DataRow dr = dt.NewRow();
  41:   
  42:                  for (int col = 0; col < 3; col++) // 列迴圈值
  43:                  {
  44:                      // 建立亂數                 避免重複值出現
  45:                      Random rnd = new Random(Guid.NewGuid().GetHashCode());
  46:                      // 1000的亂數值
  47:                      int num = rnd.Next(1000);
  48:                      // 加入到 DataRow
  49:                      dr[col] = num;
  50:                  }
  51:                  // DataRow 加到 DataTable
  52:                  dt.Rows.Add(dr);
  53:              }
  54:   
  55:              // 不好的示範 專案的名稱與SqlBulkCopy類別 撞到
  56:              System.Data.SqlClient.SqlBulkCopy sbc = new System.Data.SqlClient.SqlBulkCopy(conn);
  57:   
  58:              // 複製的目的地資料表
  59:              sbc.DestinationTableName = "dbo.DataInput";
  60:   
  61:              // 對照 資料表欄位
  62:              sbc.ColumnMappings.Add("Num1", "Num1");
  63:              sbc.ColumnMappings.Add("Num2", "Num2");
  64:              sbc.ColumnMappings.Add("Num3", "Num3");
  65:   
  66:              // 開啟資料庫連結
  67:              conn.Open();
  68:   
  69:              // 之後放進DataTable的資料
  70:              sbc.WriteToServer(dt);
  71:   
  72:              sbc.Close();
  73:              conn.Close();
  74:   
  75:              ClientScript.RegisterClientScriptBlock(this.GetType(), "寫入成功", "<script>alert('寫入成功');</script>");
  76:          }
  77:      }
  78:  }

程式下載

參考資料
(C#)使用SqlBulkCopy複製資料表到資料庫
DataColumn.DataType 屬性
請問執行asp.net後出現『字串或二進位資料會被截斷。陳述式已經結束』
[C#] 隨機產生值 v.s. Unity 隨機產生值