iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 27
1
Modern Web

淺談資料庫&ASP.net&C# 入門系列 第 27

[iT鐵人賽Day27]使用ASP.NET把檔案內的資料存進資料庫並顯示在Web頁面

經過連續好幾天的SQL介紹,今天要做的事情不是SQL介紹,而是如標題所示XD

使用ASP.NET把文字檔案的資料存進資料庫

這邊有一份2019年高雄得獎的里長的名單表格是csv檔,部分內容如下:

https://ithelp.ithome.com.tw/upload/images/20190928/20119925gQer2IqxT1.png

其實下面還有很多里長資訊就不全部截圖了><

創立資料庫及資料表

看過檔案內容後,先到SQL Server創立一個里長得獎名單的資料庫,並創好資料表的欄位,要用來存資料的。

資料庫名稱:prizeLi
資料表名稱:Li
欄位如下:
https://ithelp.ithome.com.tw/upload/images/20190928/20119925M3Zl1KcjYA.png

建立Web Form

創好資料庫及資料表後,接下來就是開啟ASP.NET並且開啟一個Web Form專案,專案名稱就叫做LiPrize。
如何建立可以參考我的團隊夥伴CynthiaChuang這篇文章,或者是碼屋( MARK WU ) 的ASP.NET系列文章。

https://ithelp.ithome.com.tw/upload/images/20190928/201199256ezugDpI5b.png

https://ithelp.ithome.com.tw/upload/images/20190928/201199255NMht6p174.png

開啟Web表單

建立好Web Form後,看到方案總管,對方案按右鍵→加入→Web表單,名字就用預設的WebForm1吧XDD
建立後可以按看看執行,執行結果會一個空白的頁面XD
到時候完成後,一進網頁就會顯示得獎名單的表格了。

https://ithelp.ithome.com.tw/upload/images/20190928/201199257IHzdsATEf.png

https://ithelp.ithome.com.tw/upload/images/20190928/20119925ollMyeia7f.png

幫Web拉一個表格和精靈與按鈕

可以到工具箱裡的資料,直接用游標把GridView(表格),及SqlDataSource(用來與資料庫做連接用的控制項),還有到標準拉一個Button按鈕,記得要拖曳到form內唷!
怎麼用游標拖曳工具到網頁,可以參考 你 說 什 麼?!網頁設計竟然可以用拉的 ( ASP.NET 伺服器控制項)

https://ithelp.ithome.com.tw/upload/images/20190928/20119925mSXue2i4on.png

如下:

https://ithelp.ithome.com.tw/upload/images/20190928/201199253HLf2d2Xom.png

接下來按到設計模式來看看感覺,恩~還ㄅ錯>< 不用自己打HTMLㄏㄏ

https://ithelp.ithome.com.tw/upload/images/20190928/20119925zrhZhptM5s.png

Button的Text可先改成"按我"。

使用SqlDataSourse控制項與SQL Server連接

現在要使用SqlDataSourse1與資料庫做連接在Web.config產生連線字串。
怎麼做連接?可以參考我之前寫的文章ASP.NET與資料庫的聯繫

對SqlDataSourse1角落的箭頭按一下,設定資料來源,然後新增連接。
https://ithelp.ithome.com.tw/upload/images/20190928/20119925YMHaCF2ZXM.png

https://ithelp.ithome.com.tw/upload/images/20190928/20119925BYecxaNqXX.png

在加入連接的頁面寫好資料庫資訊選好資料庫prizeLi的,接下來就確定ㄅ。伺服器名稱就是SQL Server的伺服器名稱,可以從登入那裡複製。 使用者驗證可以看這篇文章創立 SQL Server驗證使用者帳戶

https://ithelp.ithome.com.tw/upload/images/20190928/20119925BybZ0b85CV.png

然後按下一步,是否將連接字串存到應用程式主態檔(就是自動將連接字串加到Web.config內),打勾勾後,再下一步,然後先取得所有欄位ㄅ,所以直接勾「 * 」接下來按下一步,可以按看看測試查詢看有沒有取得資料庫,確認後按完成就可以了。

https://ithelp.ithome.com.tw/upload/images/20190928/20119925BdWkCWvGjo.png

然後可以在方案總管點開Web.config確信一下,connectionStrings有沒有連接字串。

https://ithelp.ithome.com.tw/upload/images/20190928/20119925hwZcYYNyLK.png

<connectionStrings>
    <add name="prizeLiConnectionString" connectionString="Data Source=WIN-A7UR0ON72LS\SQLEXPRESS;Initial Catalog=prizeLi;User ID=帳號;Password=密碼"
      providerName="System.Data.SqlClient" />
  </connectionStrings>

接下來對GridView1的右上角箭頭按一下選擇資料來源,選擇SqlDataSourse1,就會看到GridView1自動加入了prizeLi的資料表的欄位了,代表已經與資料庫做連接了,接下來一樣對GridView1右上角箭頭的編輯資料行將id及initDate的資料行做取消(選到欄位案紅色X就可以刪除了),按下確定後兩個欄位再GridView1都不見了。

https://ithelp.ithome.com.tw/upload/images/20190928/20119925NTHa9I0O9X.png

https://ithelp.ithome.com.tw/upload/images/20190928/20119925m45pmtUEDP.png

接下來對GridView1的右上角箭頭按一下選擇資料來源,選則「無」,然後按下「否」,不要清除已經有的欄位。
然後就可以把SqlDataSourse1控制項給砍掉了QQ(掰~)。

https://ithelp.ithome.com.tw/upload/images/20190928/20119925Y9k6U3HhBs.png

設計按鈕按下後將檔案資料存入資料庫

接下來在設計模式對Button點擊兩下,會自動跳到aspx.cs的頁面,就開始設計點擊按鈕後的動作。
現在要寫點擊按鈕後會將csv檔的資料存入prizeLi的Li資料表內。

C#程式碼如下:

string file1 = System.IO.File.ReadAllText("C:\\儲存檔案的路徑\\檔名.csv").Trim(); //取得檔案位置將資料存成字串。
string[] f_array = file1.Split('\n');//將換行做字串切割存到陣列內

string s_data = System.Web.Configuration.WebConfigurationManager.ConnectionStrings["prizeLiConnectionString"].ConnectionString;//從config找到資料庫位置[]內放的是Web.config的connectionStrings的name。
SqlConnection connection=new SqlConnection(s_data);//建立與資料庫建立起連接的通道,以s_data內的連接字串連接所對應的資料庫。

string sql = ""; //先創一個等下用來存SQL語法的空字串

connection.Open();//開啟通道   

foreach (var a in f_array)//使用foreach將f_array陣列的每一個陣列都跑一遍。
{

string[] f_array2 = a.Split(',');//將每一次跑的陣列都再以逗號進行一次分割。
                

sql = $"INSERT INTO [Li](年度, 得獎類別, 區別, 里別, 姓名)VALUES  (@year, @prize, @Chitype, @Litype, @name)";//存入插入多筆資料的SQL語法;將f_array2陣列的資料存進Li資料表欄位中。VALUES先使用@參數來取代直接給值,以防SQL Injection 程式碼。

SqlCommand command = new SqlCommand(sql, connection);//要對SQL Server下什麼SQL指令。

command.Parameters.Add("@year", SqlDbType.NVarChar);//給@參數加入資料型態
command.Parameters["@year"].Value = f_array2[0];//@參數的值是f_array2[0]
command.Parameters.Add("@prize", SqlDbType.NVarChar);
command.Parameters["@prize"].Value = f_array2[1];
command.Parameters.Add("@Chitype", SqlDbType.NVarChar);
command.Parameters["@Chitype"].Value = f_array2[2];
command.Parameters.Add("@Litype", SqlDbType.NVarChar);
command.Parameters["@Litype"].Value = f_array2[3];
command.Parameters.Add("@name", SqlDbType.NVarChar);
command.Parameters["@name"].Value = f_array2[4];

command.ExecuteNonQuery();//執行command的SQL語法,回傳受影響的資料數目。

}



connection.Close();//關閉與資料庫連線的通道

veiw();//執行副程式

稍微說明一下程式碼

1.File:開啟單一檔案的靜態方法。
2.ReadAllText:開啟文字檔,讀取所有行,並關閉;()內放路徑。
3.split字串切割:()內放的是要以什麼字串也可以放脫逸字元來做切割。可看這篇最常用的陣列!處理字串的一百種方法~(組合、切割、取代、擷取、尋找、修改)
4.ConnectionStrings: 取得連接字串config內的資訊。
5.Connection : 與資料庫建立起連接的通道。
6.Command: 下達SQL語法指令。要對資料庫下的SQL語法,必須是要一個物件才能執行,不能直接用SQL語法,所以才要把SQL丟進sqlcommand 這個物件
7.Open: 開啟與資料庫連接的通道。
8.ExecuteNonQuery: 通知資料庫執行Command所下達的SQL語法指令,並回傳受影響的資料數目。
9.foreach:通常配合陣列使用,指的是執行陣列的每一個物件,陣列有10個就跑10次,執行次數=陣列長度。
介紹可以看這篇foreach介紹

10.INSERT INTO:SQL新增資料的語法,可看這篇SQL-INSERT 新增資料的方法
11.Parameters:為了防止SQL Injection 程式碼攻擊,所以寫入SQL時,要使用參數「@參數名稱」來代替直接給的值,而給予參數的資料型態要使用Add。

在讀取文字資料還有另一種方法StreamReader

如下:

String content;


StreamReader sr = new StreamReader("C:\\Users\\蔡京叡\\source\\repos\\sqlserver1\\sqlserver1\\108.csv"); //使用StreamReader讀取文字檔

content = sr.ReadLine(); //對StreamReader做ReadLine()一行一行讀取,並存入字串變數內。


string s_data = System.Web.Configuration.WebConfigurationManager.ConnectionStrings["prizeLiConnectionString"].ConnectionString; //從config找到資料庫位置[]內放的是Web.config的connectionStrings的name。

SqlConnection connection = new SqlConnection(s_data);//建立與資料庫建立起連接的通道,以s_data內的連接字串連接所對應的資料庫。


connection.Open();//開啟通道   

while (content != null) //ReadLine()會一行一行讀取,值到讀到null時跳出迴圈
{
             
content = sr.ReadLine(); //StreamReader讀下一行
        if (!string.IsNullOrEmpty(content))//當字串不是空值或是Null時

          {
     
         string[] f_array2 = content.Split(',');//將陣列字串分割


   sql = $"INSERT INTO [Li](年度, 得獎類別, 區別, 里別, 姓名)VALUES  (@year,@prize,@Chitype, @Litype, @name)";//存入插入多筆資料的SQL語法;將f_array2陣列的資料存進Li資料表欄位中。

SqlCommand command = new SqlCommand(sql, connection);//要對SQL Server下什麼SQL指令。

  command.Parameters.Add("@year", SqlDbType.NVarChar);
  command.Parameters["@year"].Value = f_array2[0];
  command.Parameters.Add("@prize", SqlDbType.NVarChar);
  command.Parameters["@prize"].Value = f_array2[1];
  command.Parameters.Add("@Chitype", SqlDbType.NVarChar);
  command.Parameters["@Chitype"].Value = f_array2[2];
  command.Parameters.Add("@Litype", SqlDbType.NVarChar);
  command.Parameters["@Litype"].Value = f_array2[3];
  command.Parameters.Add("@name", SqlDbType.NVarChar);
  command.Parameters["@name"].Value = f_array2[4];
  
  command.ExecuteNonQuery(); //執行command的SQL語法,回傳受影響的資料數目。

          }


}
           
connection.Close();//關閉與資料庫連線

sr.Close();//關閉StreamReader
       
veiw();//執行副程式

創造一個顯示整個表格GridView1的副程式

程式碼如下:

private void veiw()//副程式名稱為:veiw()
        {
string s_data = System.Web.Configuration.WebConfigurationManager.ConnectionStrings["prizeLiConnectionString"].ConnectionString;//從config找到資料庫位置[]內放的是Web.config的connectionStrings的name。

SqlConnection connection = new SqlConnection(s_data);//建立與資料庫建立起連接的通道
SqlCommand command = new SqlCommand(@"SELECT   年度,得獎類別,區別,里別,姓名 FROM [Li]", connection);//要對SQL Server下什麼SQL指令。
connection.Open();
SqlDataReader goDataReader = command.ExecuteReader();//new一個DataReader接取ExecuteReader所執行SQL語法回傳的資料。
GridView1.DataSource = goDataReader;//告訴GridView1的資料來源是從goDataReader
GridView1.DataBind();//將資料來源與GridView1做繫結    
connection.Close();
        }

說明:

1.SqlDataReader: 一種資料流,以「順向」且「唯讀」的查看方式來讀取裡面的資料。可參考這篇ASP.NET 讀取資料庫的資料常常用到的DataReader
2.ExecuteReader: 通知資料庫執行Command所下達的SQL語法指令,並回傳資料。可以通過這個物件來查詢結果,它提供了游水式的執行方式,即從結果中讀取一列之後,指向到下一列。
3.DataBind(): 將資料來源繫結至GridView控制項。

執行結果

這樣就可以執行看看結果了。

按下「按我」就傳上資料庫並顯示了。

https://ithelp.ithome.com.tw/upload/images/20190928/20119925VrKNSxRbuN.png

https://ithelp.ithome.com.tw/upload/images/20190929/20119925eQiuXuUC0O.png

資料庫裡面也有資料了><

https://ithelp.ithome.com.tw/upload/images/20190929/20119925ETsiXF18tz.png

這樣就完成使用ASP.NET從檔案匯入資料庫了。

感謝閱讀,若有任何問題也務必要糾正指教><謝謝


上一篇
[iT鐵人賽Day26]SQL-數學運算子與數學函數
下一篇
[iT鐵人賽Day28]使用ASP.NET與SQLServer做出留言板(不包含樣式美化XDD) 上篇
系列文
淺談資料庫&ASP.net&C# 入門36

1 則留言

2
小朱
iT邦新手 4 級 ‧ 2019-09-28 19:03:21

雖然還沒寫完,但有些可以先提示。

  1. 讀文字檔可以考慮使用 StreamReader,用 ReadLine() 讀入一行,目前的作法只要 CSV 檔一大,被吃掉的記憶體也會很大,而且要一次讀入所有的內容,速度上也會有影響。
  2. 不要使用字串連結、取代等方法填 SQL,而是要用參數查詢法,這個習慣不先早點建立,日後必定會寫出很危險的 SQL Injection 程式碼。

PS: 參數查詢法:https://zh.wikipedia.org/wiki/%E5%8F%83%E6%95%B8%E5%8C%96%E6%9F%A5%E8%A9%A2

感謝小朱老師的糾正及建議><學到了可以使用StreamReader來讀取文字並用Readline()一行一行讀取的方法,使用readline()一行一行存進資料庫比起一次讀完全部資料來說也較不佔記憶體,另外我會注意使用參數查詢法的,已訂正,感謝。

我要留言

立即登入留言