主要的邏輯是撈出全部資料後,逐筆判斷該資料在另一個Table是否有相似的資料
如果有則Response出來,秀在此筆資料的下方,但如此簡單的邏輯,卻要Run很久才能跑出來
仔細看他的寫法是這樣,我以C#改寫,以使用者登入紀錄為例,我建了兩個資料表:
使用者資料表
|
登入紀錄資料表
|
當然這裡舉例的不是那麼恰當,登入紀錄應該是記錄到時分秒單位
重點是在下面這段程式:
string connString = WebConfigurationManager.ConnectionStrings["TestDBconn"].ConnectionString; SqlConnection conn = new SqlConnection(connString); SqlCommand cmd = new SqlCommand(); cmd.Connection = conn; string Sql_User = "select * from [User]"; SqlDataAdapter da = new SqlDataAdapter(Sql_User, conn); DataTable dt = new DataTable(); da.Fill(dt); if (dt.Rows.Count > 0) { for (int i = 0; i < dt.Rows.Count; i++) { //依使用者撈出登入紀錄 string Sql_Login = "select * from LoginRecord where UserID = " + dt.Rows[i]["sn"].ToString(); da = new SqlDataAdapter(Sql_Login, conn); DataTable dt_login = new DataTable(); da.Fill(dt_login); if (dt_login.Rows.Count > 0) { for (int k = 0; k < dt_login.Rows.Count; k++) { /* * Show Login Data . . . . . */ } } } }
乍看之下結果沒什麼問題,但很可怕的是逐筆連線去執行select
因如果資料可能上千上萬,甚至DB是用 Link Server的方式,
原本連線要兩秒這樣加下來就會Run到天荒地老
接著就會換來使用者的一句,程式怎麼寫那麼爛Q_Q
所以將這支程式做一點改寫,使用SQL的for XML Path語法
現在已經把該使用者登入紀錄全篩到一個新的欄位LoginData,
但這樣還是不太好閱讀,故我們用一些小技巧,把它轉為varchar
並用逗號分隔,再用Substring去除開頭的逗號:
如此已經完成抓出每個使用者的登入紀錄了,
接下來只要把這個子查詢,加入主表裡就改寫成功了:
經過這樣改寫已經把連線此數降為1次,
接下來只需要在程式裡用Split切割逗號,去秀出要的資料,
這種寫法應該是程式老手不太會犯的錯誤,
活生生的案例在實務上遇到了,也許一開始資料量小沒care這麼多
但還是養成code review的習慣以免害到後人阿!
用 STUFF 指令去除第一個逗號會比較好一點
回覆刪除感謝前輩的建議 :P
回覆刪除