1. 程式人生 > >ASP.NET SQLServer 行轉列,不固定列,動態列 的實現

ASP.NET SQLServer 行轉列,不固定列,動態列 的實現

前言

剛開始工作就成了被溫水煮的青蛙的話,那該有多難吃啊。所以要保持冷靜的頭腦,好好思考自己該做的不該做的事,好好的提升自己的能力,給自己加點料。嗯,這樣就算真被煮熟了,也會可口很多吧。

問題背景

這個問題是前面工作中遇到的,經過一番努力最終解決了。在這裡把問題以及解決思路總結一下。

問題描述

sql server 資料庫裡有兩張表,主表和明細表;最終需要在前端頁面顯示錶格,要求是以主表為基礎的、將明細表的資料作為動態列附加到對應行上 ;

這裡我們給出實驗用的表格以及最終需要顯示的樣子:

主表table1:

##################1###############

明細表table2:

########################2##########

需要顯示的樣式:

#####################final#############

解決思路

主要分兩步,第一步是將資料轉化為如下格式:

###########################3

第二步是用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

這樣就實現了第一步啦

##########################4
前端程式碼先給出:

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

這樣子就實現了最終的目標啦:

####################final