刚会点动态生成Table,其实也不知道是不是叫动态生成Table,但是这个不重要.本来写篇博客介绍点中心思想就好了,但是我偏不,非要作死,想要完整的介绍这个是如何做的.
然后自己建立数据库,自己建项目,写代码.但是吧,写了一部分代码发现,数据库只建立了一个表,完全没有动态显示的必要,直接用GridView就可以搞定.然后就想加两个表吧,思路没理清,开始建表,填数据,写了大半天,发现还是理不清,好像还是不对的样子.最后好不容易算是理清思路了,建立了3个表,但是字段总觉得不对,联合查询不是查的比我要的多,就是查不到数据.相当郁闷啊.最后总算弄出一个能见人的了.
在做之前,先弄个功能说明.
功能说明:
根据数据库中查询出的结果,生成行列不固定的Table,前几列显示数据,最后一列,对一行的数据进行汇总。Table预期效果大约如下:
学年 | 第1年 | 第2年 | 总分 |
英语 | 80 | 70 | 150 |
数学 | 30 | 40 | 70 |
学年 | 第1年 | 第2年 | 第3年 | 总分 |
英语 | 80 | 70 | 90 | 240 |
数学 | 30 | 40 | 50 | 120 |
语文 | 40 | 60 | 80 | 180 |
事先说明下,我最后做出来的和这个还是有区别的,首先行列颠倒了,这样比较符合实际情况.其实这个做出来应该也不难,奈何设计数据库,废了我太多脑子,所以...
接下来先看下,数据库的sql语句.非常详细,差不多我建表的整个过程都在这了.
Sql语句
----创建TestTable数据库
create database TestTable
----删除表
--use TestTable
--drop table T_Stu
--use TestTable
--drop table T_Course
--use TestTable
--drop table T_Score
--创建T_Stu表
create table T_Stu
(
stuNo varchar(5) not null,--学生学号
stuName varchar(10) null, --学生姓名
grade varchar(5) null --年级
)
--创建T_Course表
use TestTable
create table T_Course
(
courseNo varchar(5) not null, --课程编号
courseName varchar(10) null --课程名
)
--创建T_Score表
use TestTable
create table T_Score (
stuNo varchar(5) null, --学生姓名
courseNo varchar(5) , --课程编号
stuYear varchar(5) , --学年
score varchar(5) null --课程分数
)
--给表插入数据
--学生表插入学生
--小红,学号1,年级1;
--小蓝,学号2,年级2;
insert into T_Stu values('1','小红','1')
insert into T_Stu values('2','小蓝','2')
--课程表插入课程
--有三门课,编号为101的语文,102的数学,103的英语
insert into T_Course values('101','语文')
insert into T_Course values('102','数学')
insert into T_Course values('103','英语')
--delete from T_Score
--小红和小蓝的成绩,小红只有1年的成绩,小蓝有2年的成绩
--小红的语文,数学,英语的成绩
insert into T_Score values('1','101','1','80')
insert into T_Score values('1','102','1','70')
insert into T_Score values('1','103','1','60')
--小蓝1年级和2年级的语文,数学,英语成绩
insert into T_Score values('2','101','1','40')
insert into T_Score values('2','102','1','60')
insert into T_Score values('2','103','1','90')
insert into T_Score values('2','101','2','70')
insert into T_Score values('2','102','2','80')
insert into T_Score values('2','103','2','60')
select * from T_Stu
select * from T_Course
select * from T_Score
--在T_Stu表中,查询出学生的年级
--小蓝是二年级的,所以分数表中会有2年的成绩
select * from T_Stu where stuNo='2'
--在课程表中,查询出学生的课程
--课程有三门
select * from T_Course
--在分数表中,查询出学生的分数
--小蓝一年级的时候的语文成绩
select * from T_Score where stuNo='2' and courseNo='101' and stuYear='1'
--小蓝二年级的时候的数学成绩
select * from T_Score where stuNo='2' and courseNo='102' and stuYear='2'
--总分,小蓝同学第一年的时候的总成绩
select sum(cast(score as int)) from T_Score where stuNo='2' and stuYear='1'
简单说明下数据库的内容,尽管注释个人觉得写得还是很好的.建立了三个表T_Stu学生表,T_Course课程表,T_Score分数表.然后学生表是学生的信息,学号,姓名和年级.课程就只有课程号和课程名.本来打算的是,年级不同,课程不同,最后被自己绕晕了,所以里面就只有三门课了.还有就是分数表,学号,课程号,学年和课程分数.一年级的在这里只有1条记录,2年级的有两条.依次类推.
查询过程是,根据学号或学生姓名,在学生表中查询到学生的年级,然后根据年级,开始动态生成行;查询课程,获取课程数目,动态生成列.先建立表头,然后再填充数据,数据主要从T_Score表中查询出来.
对于最后总分查询,由于我的字段都是varchar类型,所以要转换字段类型,用cast(字段名 as int),将字段转为int类型,才能用sum函数,计算总分.
然后就是前台界面的代码和界面效果.
1.新建--网站--ASP.NET空网站,TestTable
2.添加新项--Web窗体,Test.aspx
3.前台添加一个控件,代码如下
前台代码
<form id="form1" runat="server">
<div><asp:Label ID="Label1" runat="server" Text="Label">学号请输入1或2;姓名请输入小红或小蓝</asp:Label> </div>
<asp:RadioButton ID="rbnStuNo" runat="server" GroupName="tbTest1" Text="学号" />
<asp:RadioButton ID="rbnStuName" runat="server" GroupName="tbTest1" Text="姓名" />
<asp:TextBox ID="txtQuery" runat="server"></asp:TextBox>
<asp:LinkButton ID="lbtQuery" runat="server" OnClick="lbtQuery_Click1">查询</asp:LinkButton>
<asp:Table ID="tbTest" runat="server">
</asp:Table>
</form>
接着是后台代码
后台代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;
using System.Windows.Forms;
namespace TestTable
{
public partial class Test : System.Web.UI.Page
{
//连接数据库字符串
string strConn = "server=.;database=TestTable;uid=sa;pwd=123456";
//创建连接
SqlConnection conn;
//创建命令
SqlCommand cmd;
protected void Page_Load(object sender, EventArgs e)
{
}
protected void lbtQuery_Click1(object sender, EventArgs e)
{
//获取查询条件
string strWhere = "";
//如果选中学号
if (rbnStuNo.Checked)
{
//获取文本框中的值,拼凑查询条件
strWhere = "stuNo='" + txtQuery.Text + "'";
//strWhere = Request.Form["txtQuery"];
//strWhere = "stuNo='" + strWhere + "'";
}
else
{
//选中的是姓名
//获取文本框中的值,拼凑查询条件
strWhere = "stuName='" + txtQuery.Text + "'";
//strWhere = Request.Form["txtQuery"];
//strWhere = "stuName='" + strWhere + "'";
}
//拼凑好的查询条件,作为参数,调用bind方法
bind(strWhere);
}
//动态生成Table
private void bind(string strWhere)
{
//获取小蓝的成绩,
//查询学生信息表,获取学生的信息,包括学生,姓名和年级
string strSql = "select * from T_Stu where " + strWhere;
DataTable dt = QueryScore(strSql);
//获取小蓝的年级和学号
int grade = int.Parse(dt.Rows[0]["grade"].ToString());
string stuNo = dt.Rows[0]["stuNo"].ToString();
//获取课程数
string strSql1 = " select * from T_Course";
//获取课程数和课程信息(课程编号,课程名)
DataTable dtCourse = QueryScore(strSql1);
int intCourseNum = dtCourse.Rows.Count;
//根据查询出来的数据行数,确定table
for (int i = 0; i < grade; i++)
{
//构建表头
if (i == 0)
{
//实例化TableRow和TableCell
//第一行,表头
TableRow tR = new TableRow();
//第一个单元格
TableCell tC1 = new TableCell();
tC1.Text = "科目";
//单元格添加到行中
tR.Controls.Add(tC1);
//第二个,第三个单元格(第四个)
for (int r = 0; r < intCourseNum; r++)
{
TableCell tC2 = new TableCell();
//语文,数学,英语
tC2.Text = dtCourse.Rows[r]["courseName"].ToString();
tR.Controls.Add(tC2);
}
//最后一个单元格
TableCell tC3 = new TableCell();
tC3.Text = "总分";
//添加到行中
tR.Controls.Add(tC3);
//把表头添加到Table中
tbTest.Controls.Add(tR);
}
//建立其他行
if (i >= 0)
{
//实例化TableRow和TableCell
//第一行,表头
TableRow tR = new TableRow();
//第一个单元格
TableCell tC1 = new TableCell();
//给第一列的单元格赋值,第一年,第二年
tC1.Text = "第" + (i + 1) + "年";
//添加到行中
tR.Controls.Add(tC1);
//第二列,第三列(第四列)(语文,数学,英语的分数)
for (int r = 0; r < intCourseNum; r++)
{
TableCell tC2 = new TableCell();
//拼凑Sql语句,查询学生第i+1年的某科目的分数
string strSql2 = "select * from T_Score where ";
strSql2 = strSql2 + "stuNo='" + stuNo + "'";
strSql2 = strSql2 + " and courseNo='" + dtCourse.Rows[r]["courseNo"] + "'";
strSql2 = strSql2 + " and stuYear='" + (i + 1) + "'";
DataTable dtScore = QueryScore(strSql2);
//获取到分数
tC2.Text = dtScore.Rows[0]["score"].ToString();
tR.Controls.Add(tC2);
}
//最后一列汇总
TableCell tC3 = new TableCell();
string strSql3 = "select sum(cast(score as int)) from T_Score where stuNo='" + stuNo + "' and stuYear='" + (i + 1) + "'";
DataTable dtSum = QueryScore(strSql3);
tC3.Text = dtSum.Rows[0][0].ToString();
tR.Controls.Add(tC3);
//第一行,第二行数据添加到Table中
tbTest.Controls.Add(tR);
}
}
}
/// <summary>
/// 根据条件查询数据库
/// </summary>
/// <param name="strSql">sql语句</param>
/// <returns></returns>
private DataTable QueryScore(string strSql)
{
//创建连接
conn = new SqlConnection(strConn);
//打开连接
conn.Open();
//新建命令
cmd = new SqlCommand(strSql, conn);
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.SelectCommand = cmd;
DataSet ds = new DataSet();
adapter.Fill(ds);
return ds.Tables[0];
}
}
}
运行效果:
查小红,一条记录;
查小蓝,两条记录
以上就是我弄出来的动态生成Table.所有代码在一个页面里,没有做任何出错处理.代码比较从简.呵呵,总算弄完了,不容易啊.