ASP.NET SQLServer 行轉列,不固定列,動態列 的實現
阿新 • • 發佈:2018-12-31
前言
剛開始工作就成了被溫水煮的青蛙的話,那該有多難吃啊。所以要保持冷靜的頭腦,好好思考自己該做的不該做的事,好好的提升自己的能力,給自己加點料。嗯,這樣就算真被煮熟了,也會可口很多吧。
問題背景
這個問題是前面工作中遇到的,經過一番努力最終解決了。在這裡把問題以及解決思路總結一下。
問題描述
sql server 資料庫裡有兩張表,主表和明細表;最終需要在前端頁面顯示錶格,要求是以主表為基礎的、將明細表的資料作為動態列附加到對應行上 ;
這裡我們給出實驗用的表格以及最終需要顯示的樣子:
主表table1:
明細表table2:
需要顯示的樣式:
解決思路
主要分兩步,第一步是將資料轉化為如下格式:
第二步是用C#程式碼處理資料,使其變為最終需要的格式。
具體實現
select a.*,
stuff((select ',' + t.task from table2 as t where t.name=a.name for xml path('')),
1,1,'') as task
from table1 as a
這樣就實現了第一步啦
前端程式碼先給出:
<form id="form1" runat="server"> <div> <p>This is the Table:</p> <table border="1"> <asp:Label runat ="server" ID="lblTable"></asp:Label> </table> </div> </form>
現在我們只需要在後臺拼接table的html程式碼,賦值給lblTable即可。
後臺,我們需要來將task列分成多列,而且這個列數是不固定數量的、隨著task內容的變動而變動。
protected void Page_Load(object sender, EventArgs e) { SqlConnection cn = new SqlConnection(); cn.ConnectionString = "server=.;uid=sa;pwd=自己的密碼;database=自己的資料庫"; cn.Open(); string sqlstr = @" select a.*, stuff((select ',' + t.task from table2 as t where t.name = a.name for xml path('')), 1,1,'') as task from table1 as a "; SqlCommand cmd = new SqlCommand(); cmd.Connection = cn; cmd.CommandText = sqlstr; SqlDataReader reader = cmd.ExecuteReader(); DataTable dt = ReaderToTable(reader); dt = DealTable(dt); string htmlStr = GetHtmlStrByDataTable(dt); lblTable.Text = htmlStr; } protected DataTable ReaderToTable(SqlDataReader dr) { DataTable dt = new DataTable(); for (int i = 0; i < dr.FieldCount; i++) { dt.Columns.Add(dr.GetName(i), dr.GetFieldType(i)); } object[] objValues = new object[dr.FieldCount]; while (dr.Read()) { dr.GetValues(objValues); dt.LoadDataRow(objValues, true); } dr.Close(); return dt; } protected DataTable DealTable(DataTable dt) { //獲取task列資料,存入list List<string[]> list = new List<string[]>(); for(int i=0;i<dt.Rows.Count;i++) { string[] strs = dt.Rows[i]["task"].ToString().Split(','); list.Add(strs); } //取得strs中最長的長度 int maxlen = 0; foreach(string[] strs in list) { if (strs.Length>maxlen) { maxlen = strs.Length; } } //刪除task列 dt.Columns.Remove("task"); //新增maxlen個列 for(int i=0;i<maxlen;i++) { dt.Columns.Add("task" + (i + 1).ToString()); } //給新新增的列賦值資料 int newColStart = dt.Columns.IndexOf(dt.Columns["name"])+1; for (int i=0;i<dt.Rows.Count;i++) { for(int j=newColStart;j<newColStart+maxlen;j++) { int newColNo = j - newColStart; if (list[i].Length>newColNo) { dt.Rows[i][j] = list[i][newColNo]; } } } return dt; } protected string GetHtmlStrByDataTable(DataTable dt) { StringBuilder sb = new StringBuilder(); //表頭 sb.Append("<tr>"); for (int i = 0; i < dt.Columns.Count; i++) { sb.Append("<td>" + dt.Columns[i].ColumnName + "</td>"); } sb.Append("</tr>"); //資料 for (int i = 0; i < dt.Rows.Count; i++) { sb.Append("<tr>"); for (int j = 0; j < dt.Columns.Count; j++) { sb.Append("<td>" + dt.Rows[i][j].ToString() + "</td>"); } sb.Append("</tr>"); } return sb.ToString(); }
這樣子就實現了最終的目標啦: