ASP.NET SQLServer 行转列,不固定列,动态列 的实现

xiaoxiao2021-02-28  93

前言

刚开始工作就成了被温水煮的青蛙的话,那该有多难吃啊。所以要保持冷静的头脑,好好思考自己该做的不该做的事,好好的提升自己的能力,给自己加点料。嗯,这样就算真被煮熟了,也会可口很多吧。

问题背景

这个问题是前面工作中遇到的,经过一番努力最终解决了。在这里把问题以及解决思路总结一下。

问题描述

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(); }

这样子就实现了最终的目标啦:

转载请注明原文地址: https://www.6miu.com/read-18550.html

最新回复(0)