某高校学生成绩单案例
u本节内容包括:
n打印某高校学生成绩单案例简介
n打印某高校学生成绩单实验步骤
n打印某高校学生成绩单(动态数据)案例
某高校标准的学生成绩单的纸质报表样式如图6-1所示。该纸质报表是一种典型的汇总统计型报表,具有典型的报表页眉,页脚及详细资料显示区域,同时在页脚必须实现对学生成绩的综合成绩统计工作。因此,掌握该类型报表的设计工作,对一般复杂类型的水晶报表就可以完全设计出来了。
图6-1 学生成绩单纸质报表样式
u实验步骤1:
建立一个空的rpt文件,首先进行整个报表的纸张大小设置,这一点对于后期打印报表和报表布局非常重要。根据办公室人员介绍,该报表的打印纸张必须是B5型打印纸。向有关人员要来成绩单电子文档,通过Word软件打开文件后,查看该Word文档的页面设置如图6-2所示。
图6-2 电子Word文档的页面设置参数配置
从Word文档的页面设置参数信息可以得出,纸质大小为16开,上下边距2.54厘米,左右边距3.17厘米。这些参数将为水晶报表的格式化定制提供标准的设计参数。
u实验步骤2:
回到新建立的rpt文件,用鼠标右键单击报表界面,在弹出的对话框中选择当前报表的打印机设置选项,将纸张大小设置成为B5纸,纵向。如图6-3所示。
图6-3 水晶报表的打印设置
u 实验步骤3:
再用鼠标右键单击报表界面,在弹出的对话框中选择当前报表的页面设置选项,按照WORD文档页边距参数进行配置。如图6-4所示。
图6-4 水晶报表的页边距设置
u 实验步骤4:
设置报表页眉,该处文本仅仅在第一页头部出现。从报表的工具箱中选择文本对象,拖到报表页眉处,在报表页眉处键入字样后,点击右键选择设置对象格式。依次将报表页眉文字进行与纸质报表对应文字字体格式的设置,最终形成的样式如图6-5所示。
图6-5 设置水晶报表的报表页眉文字格式
u实验步骤5:
设计页眉部分,该部分文本将在每页的头部处出现。此次页眉部分为表格的表头部分,包括的内容有:学生学号,姓名,平时成绩,设计成绩,考试成绩,总评成绩,共6项内容。由于报表左侧第一单元格线段是斜线,无法通过工具箱的控件实现,故需要通过绘图软件做成图片后填充该区域。通过右键点击页眉处,选择图片,将制作好的图片插入左侧页眉处。而后,以该图片的高设定为页眉行高,宽度为第一单元格宽度。从工具箱之中拖拽框对象,此处需要注意的是,绘制边框时候,页眉和详细资料全部一起框住,这样产生的报表样式可以统一美观。最终形成的样式如图6-6所示。
图6-6 水晶报表的表头页眉设置过程
u 实验步骤6:
选择工具箱之中的线条对象,在页眉处绘制出四个单元格,准备添加相关的文字信息。如图6-7所示。
图6-7 水晶报表的表头页眉绘制分割线
u 实验步骤7:
配置水晶报表数据源,该类型水晶报表的设计开发必须采用Push模式进行设计。用右键点击报表界面,在弹出的菜单中选择数据库->数据库专家,在弹出的OLE DB(ADO)界面中选择OLE DB Provider SQL Server,并配置数据库服务器连接信息。此次选择的数据库为示例数据库Grade_Sys(成绩管理数据库),以sa用户身份登录,无密码。选择完成后,打开菜单中的水晶报表项里面的字段资源管理器,准备将展开的数据库字段拖拽到报表界面上面。如图6-8所示。
图6-8 水晶报表的数据源信息配置流程
u 实验步骤8:
将页眉处文字按照图6-29写入,并配置字体大小,同时用线条对象勾勒出表格的基本数据分布区域。以页眉表格为基准,在详细资料处同样绘制相应的表格单元。将详细资料各个单元格需要的数据从字段管理器的数据库字段拖拽过来(此次应用的单表为sc表,该表为学生成绩表,具体格式请读者恢复Grade_Sys数据库后,自行查看),把属性字段删除分布在页眉的部分后,将实际字段分别排列在详细资料的空格内。
图6-9 水晶报表的详细资料部分设计和表头文字设计
u 实验步骤9:
配置报表页脚部分,该部分仅仅在水晶报表最后一页尾部出现。从工具箱中拖拽文本,线条和框对象共同组成下图在页脚部分的样式。
图6-10 水晶报表页脚部分设计
u 实验步骤10:
右键点击报表页面,选择报表->节专家,在打开的节专家设计器里面,勾选在页面底部打印功能。此功能可以使得报表页脚仅仅在最后一页的底部显示。如图6-11所示。
图6-11 设置水晶报表报表页脚仅仅在最后一页的底部显示
u 实验步骤11:
整体设计完成后的报表如下图所示,点击主报表预览,可以预览报表基本样子。如图6-12所示为最终设计效果。
图6-12 水晶报表最终设计效果
u实验步骤12:
回到form1界面,从水晶报表中拖出一个crystalReportViewer对象,并配置该crystalReportViewer对象的reportsource属性为刚才设计的rpt文件。运行form1,程序一切正常,主要问题是:
Ø报表头非动态变化的数据;
Ø显示的学生成绩内容并非一个班的,而是所有的学生成绩。
Ø每门课程的百分比非动态变化的,毕竟每个教师给出的百分比都不尽相同。
Ø报表页脚的信息是静态不变的。
很显然,离真实的动态报表还是相距甚远,我们将在下一节详细介绍动态水晶报表技术,其中的水晶报表文件仍然是我们设计的这个rpt文件。如图6-13为水晶报表属性配置图,6-14为最终运行效果图。
图6-13 水晶报表数据源配置
图6-14 水晶报表运行效果图
要想获取图6-14中某门课程某个班级的成绩表,除了必须获取课程号和班级号这两个主键以外,还必须获取的信息包括:某门课程某个班级教师阅卷时候设定的考试成绩百分比值,以及参加该门课程考试的学生各个考试类型具体的成绩,同时也必须获取相应的学期信息、课程名、专业名、班级名,而且在系统运行最后应当将考试成绩的统计资料信息一并显示出来。因此,完成此案例涉及知识面广,设计程序代码比较复杂。
u实验步骤1:
由于该项目设计数据库复杂操作,故而提前建立两个类文件:BuessinessLayer.cs和databaselayer.cs,分别代表业务逻辑部分代码和数据库部分代码。有关databaselayer.cs的封装方法,在ADO.NET章节已经有所论述,此处不再展开;对于BuessinessLayer.cs中用到的方法,随着案例的推进将注意讲解分析。
图6-15 建立业务逻辑类和数据库类文件
u实验步骤2:
将上一节建立的rpt文件拷贝到当前WinForm项目的执行目录内(即当前项目的\bin\Debug\目录下面)。同时再建立一个新的Form窗体,该窗体主要实现通过选择班级和课程显示课程水晶报表的功能,其界面如图6-16所示。
图6-16 通过选择班级和课程显示课程水晶报表
在当前窗体的Load事件中键入如下代码:
|
/// <summary> /// 窗体加载事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Form4_Load(object sender, EventArgs e) { //班级信息加载 string sql1 = "select bno,bname from class"; DataSet ds1 = DB.GetDataSet(sql1); comboBox1.DataSource = ds1.Tables[0].DefaultView; comboBox1.DisplayMember = "bname"; comboBox1.ValueMember = "bno"; //课程信息加载 string sql2 = "select cno,cname from course"; DataSet ds2 = DB.GetDataSet(sql2); comboBox2.DataSource = ds2.Tables[0].DefaultView; comboBox2.DisplayMember = "cname"; comboBox2.ValueMember = "cno"; } |
双击窗体的”显示水晶报表”按钮,进入按钮单击事件:
|
/// <summary> /// 准备打开水晶报表文件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button1_Click(object sender, EventArgs e) { object bno = this.comboBox1.SelectedValue; object cno = this.comboBox2.SelectedValue; string s = "select scno from sc where cno=" + cno.ToString() + " and bno=" + bno.ToString(); //查询是否选择的课程编号和班级编号有成绩信息 if (DB.GetdataRow("select scno from sc where cno=" + cno.ToString() + " and bno=" + bno.ToString()) > 0) { Form //重载Show方法,打开form1时候,传递cno 课程号和 bno 班级号参数过去 f.Show(); } else { MessageBox.Show("该班级该课程无成绩信息!"); } } |
u实验步骤3:
打开Form1窗体,该窗体仅仅有一个crystalReportViewer控件,用来显示来自水晶报表的数据信息。
图6-17 Form1窗体
进入Form1窗体的代码编辑文件,键入如下代码:
|
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using CrystalDecisions.Shared; using CrystalDecisions.CrystalReports.Engine; //注意:必须增加水晶报表的这两个命名空间才可以在编程状态下操作水晶报表对象。 namespace WindowsApplication1 { public partial class Form1 : Form { Buessiness business = new Buessiness();//实例化业务逻辑层,具体方法在下面分述介绍 Mydatabase db = new Mydatabase();//实例数据库层,具体方法在ADO.NET已有介绍 //此处的重载,接收来自外部的系统参数,课程号cno和班级号bno public Form1(object cno,object bno) { InitializeComponent(); //初始化界面各个参数 int percent_qm, percent_sj, percent_ps, ctime; //获取表头三项成绩百分比。 business.GetCoursecheck(Convert.ToInt32(cno), Convert.ToInt32(bno), out percent_qm, out percent_sj, out percent_ps); //第一个业务逻辑层的方法,请见下面的介绍。 string xqmess, cname, zy, nj, bname, tname, year1, month1, day1, clx_string; Int16 clx_num; //获取表头标题各项信息 business.GetPaperMessage(Convert.ToInt32(cno), Convert.ToInt32(bno), 2, out xqmess, out cname, out zy, out nj, out bname, out tname, out year1, out month1, out day1, out clx_num, out clx_string, out ctime); //第二个业务逻辑层的方法,请见下面的介绍。 //获取表尾统计信息 int first, second, third, forth, fifth, total1; business.GetPjStatistics(Convert.ToInt32(cno), Convert.ToInt32(bno), out first, out second, out third, out forth, out fifth, out total1); //第三个业务逻辑层的方法,请见下面的介绍。 //注意学习如何获取磁盘内的水晶报表的rpt文件 string path = Environment.CurrentDirectory + "\\CrystalReport1.rpt"; ReportDocument report = new ReportDocument(); report.Load(path);//加载报表
((TextObject)report.ReportDefinition.ReportObjects["Text_title1"]).Text = xqmess; ((TextObject)report.ReportDefinition.ReportObjects["Text_cname"]).Text = cname; ((TextObject)report.ReportDefinition.ReportObjects["Text3"]).Text = zy; ((TextObject)report.ReportDefinition.ReportObjects["Text5"]).Text = bname;
//下面是表尾部分: ((TextObject)report.ReportDefinition.ReportObjects["Text_yx"]).Text = first.ToString(); ((TextObject)report.ReportDefinition.ReportObjects["Text_lh"]).Text = second.ToString(); ((TextObject)report.ReportDefinition.ReportObjects["Text_zd"]).Text = third.ToString(); ((TextObject)report.ReportDefinition.ReportObjects["Text_jg"]).Text = forth.ToString(); ((TextObject)report.ReportDefinition.ReportObjects["Text_nojg"]).Text = fifth.ToString(); ((TextObject)report.ReportDefinition.ReportObjects["Text_totalnum"]).Text = total1.ToString();
//下面是显示标头各个分值的百分比 ((TextObject)report.ReportDefinition.ReportObjects["Text19"]).Text = percent_ps.ToString(); ((TextObject)report.ReportDefinition.ReportObjects["Text21"]).Text = percent_sj.ToString(); ((TextObject)report.ReportDefinition.ReportObjects["Text25"]).Text = percent_qm.ToString();
//下面是写年月日信息 ((TextObject)report.ReportDefinition.ReportObjects["Text38"]).Text = year1.ToString(); ((TextObject)report.ReportDefinition.ReportObjects["Text39"]).Text = month1.ToString(); ((TextObject)report.ReportDefinition.ReportObjects["Text40"]).Text = day1.ToString(); ((TextObject)report.ReportDefinition.ReportObjects["Text43"]).Text = year1.ToString(); ((TextObject)report.ReportDefinition.ReportObjects["Text42"]).Text = month1.ToString(); ((TextObject)report.ReportDefinition.ReportObjects["Text41"]).Text = day1.ToString();
//下面开始动态加载SQL脚本,此次是通过dataset加载水晶报表 DataSet Ds = db.GetDataSet("select snumber,sname,Grade,Grade_ps,Grade_end,Grade_design from sc where cno=" + Convert.ToString(cno) + " and bno=" + Convert.ToString(bno)); report.SetDataSource(Ds.Tables[0]); //最后绑定数据源,不写无法显示哦^o^ this.crystalReportViewer1.ReportSource = report; } } } |
u实验步骤4:
下面分别介绍上面主程序部分设计的业务逻辑层方法的具体代码,由于这些方法都是引用了数据库存储过程部分,故而同时将展示存储过程开发的代码部分。
1、业务逻辑层方法business.GetCoursecheck的设计
|
/******************************************************* **方 法 名:GetCoursecheck **输 入参数:cno课程编号 bno班级编号 **输 出参数: **返 回 值: **创 建 人:钱哨 **创 建日期: **描 述:通过存储过程输入cno课程编号和bno班级编号,判别该班该门课程是否有判卷,如果没有则需要进行考试表的初始化工作。 *******************************************************/ public void GetCoursecheck(int cno, int bno, out int percent_qm, out int percent_sj, out int percent_ps) { ///下面,开始实例化另一个命名空间的一个类 Mydatabase DB = new Mydatabase(); string sql = String.Format("exec proc_GetCoursecheck " + cno + "," + bno + ",@percent_qm output,@percent_ps output,@percent_sj output"); //执行的T-SQL串 SqlCommand MyCommand = DB.GetProcCommand(sql); MyCommand.Parameters.Add(new SqlParameter("@percent_qm", SqlDbType.Int)); MyCommand.Parameters.Add(new SqlParameter("@percent_ps", SqlDbType.Int)); MyCommand.Parameters.Add(new SqlParameter("@percent_sj", SqlDbType.Int));
MyCommand.Parameters["@percent_qm"].Direction = ParameterDirection.Output; MyCommand.Parameters["@percent_ps"].Direction = ParameterDirection.Output; MyCommand.Parameters["@percent_sj"].Direction = ParameterDirection.Output; MyCommand.ExecuteNonQuery(); percent_qm = Convert.ToInt16(MyCommand.Parameters["@percent_qm"].Value); //接收输出的参数 percent_ps = Convert.ToInt16(MyCommand.Parameters["@percent_ps"].Value); percent_sj = Convert.ToInt16(MyCommand.Parameters["@percent_sj"].Value); DB.close(); } |
该方法中引用的存储过程proc_GetCoursecheck代码如下:
|
create proc proc_GetCoursecheck --通过存储过程输入cno课程编号和bno班级编号,判别该班该门课程是否有判卷,如果没有则需要进行考试表的初始化工作。 @cno int, @bno int, @percent_qm int output, @percent_ps int output, @percent_sj int output as if exists(select sno from sc where cno=@cno and bno=@bno) begin select top 1 @percent_ps=Grade_ps_percent,@percent_qm=Grade_end_percent,@percent_sj=Grade_design_percent from sc where cno=@cno and bno=@bno
end
else begin --先求一下该课程和班级的派课表中的授课学期信息 declare @skxq varchar(10) select @skxq=skxq from tc where bno=@bno and cno=@cno --如果成绩表中没有该班级该门课程的任何成绩,则需要将学生表的数据复制过来 insert into sc(cno,bno,sno,sname,snumber,Grade_ps_percent,Grade_end_percent,Grade_design_percent,skxq) select @cno,bno,sno,sname,snumber,20,80,0,@skxq from student where bno=@bno set @percent_ps=20 set @percent_qm=80 set @percent_sj=0 end
GO |
2、 业务逻辑层方法business.GetPjStatistics方法设计
|
/******************************************************* **方 法 名:GetPjStatistics **输 入参数:int bno班级号码, int cno课程号码 **输 出参数: **返 回 值: **创 建 人:钱哨 **创 建日期: **描 述:统计试卷各个分值的人数。 *******************************************************/ public void GetPjStatistics(int cno, int bno, out int first, out int second, out int third, out int forth, out int fifth, out int total) { ///下面,开始实例化另一个命名空间的一个类 Mydatabase DB = new Mydatabase(); string sql = String.Format("exec proc_PjStatistics " + cno + "," + bno + ",@first output,@second output,@third output,@forth output,@fifth output,@total output"); //执行的T-SQL串 SqlCommand MyCommand = DB.GetProcCommand(sql); MyCommand.Parameters.Add(new SqlParameter("@first", SqlDbType.Int)); MyCommand.Parameters.Add(new SqlParameter("@second", SqlDbType.Int)); MyCommand.Parameters.Add(new SqlParameter("@third", SqlDbType.Int)); MyCommand.Parameters.Add(new SqlParameter("@forth", SqlDbType.Int)); MyCommand.Parameters.Add(new SqlParameter("@fifth", SqlDbType.Int)); MyCommand.Parameters.Add(new SqlParameter("@total", SqlDbType.Int));
MyCommand.Parameters["@first"].Direction = ParameterDirection.Output; MyCommand.Parameters["@second"].Direction = ParameterDirection.Output; MyCommand.Parameters["@third"].Direction = ParameterDirection.Output; MyCommand.Parameters["@forth"].Direction = ParameterDirection.Output; MyCommand.Parameters["@fifth"].Direction = ParameterDirection.Output; MyCommand.Parameters["@total"].Direction = ParameterDirection.Output;
MyCommand.ExecuteNonQuery();
first = Convert.ToInt32(MyCommand.Parameters["@first"].Value); //接收输出的参数 second = Convert.ToInt32(MyCommand.Parameters["@second"].Value); third = Convert.ToInt32(MyCommand.Parameters["@third"].Value); forth = Convert.ToInt32(MyCommand.Parameters["@forth"].Value); fifth = Convert.ToInt32(MyCommand.Parameters["@fifth"].Value); total = Convert.ToInt32(MyCommand.Parameters["@total"].Value); DB.close(); } |
该方法中引用的存储过程proc_PjStatistics代码如下:
|
create proc proc_PjStatistics @cno int, @bno int, @first int output,@second int output,@third int output,@forth int output,@fifth int output,@total int output as select @fifth=count(sno) from sc where (Grade>=0 and Grade<60) and bno=@bno and cno=@cno select @forth=count(sno) from sc where (Grade>=60 and Grade<70) and bno=@bno and cno=@cno select @third=count(sno) from sc where (Grade>=70 and Grade<80) and bno=@bno and cno=@cno select @second=count(sno) from sc where (Grade>=80 and Grade<90) and bno=@bno and cno=@cno select @first=count(sno) from sc where (Grade>=90 and Grade<=100) and bno=@bno and cno=@cno select @total=count(sno) from sc where bno=@bno and cno=@cno
GO |
3、 业务逻辑层方法business.GetPaperMessage设计
|
/******************************************************* **方 法 名:GetPaperMessage **输 入参数:课程号码和班级号码,教师编号 **输 出参数: **返 回 值: **创 建 人:钱哨 **创 建日期: **描 述:通过存储过程获取试卷界面的参数信息。 *******************************************************/ public void GetPaperMessage(int cno, int bno, int tno, out string xqmess, out string cname, out string zy, out string nj, out string bname, out string tname, out string year1, out string month1, out string day1, out Int16 @clx_num, out string @clx_string, out int @ctime) { ///下面,开始实例化另一个命名空间的一个类 Mydatabase DB = new Mydatabase(); string sql = String.Format("exec proc_fdpaper " + cno + "," + bno + "," + tno + ",@xqmess output, @cname output,@zy output, @nj output,@bname output,@tname output,@year1 output,@month1 output,@day1 output,@clx_num output,@clx_string output,@ctime output"); //执行的T-SQL串 SqlCommand MyCommand = DB.GetProcCommand(sql); MyCommand.Parameters.Add(new SqlParameter("@xqmess", SqlDbType.VarChar, 100)); MyCommand.Parameters.Add(new SqlParameter("@cname", SqlDbType.VarChar, 50)); MyCommand.Parameters.Add(new SqlParameter("@zy", SqlDbType.VarChar, 40)); MyCommand.Parameters.Add(new SqlParameter("@nj", SqlDbType.VarChar, 20)); MyCommand.Parameters.Add(new SqlParameter("@bname", SqlDbType.VarChar, 30)); MyCommand.Parameters.Add(new SqlParameter("@tname", SqlDbType.VarChar, 40)); MyCommand.Parameters.Add(new SqlParameter("@year1", SqlDbType.VarChar, 10)); MyCommand.Parameters.Add(new SqlParameter("@month1", SqlDbType.VarChar, 10)); MyCommand.Parameters.Add(new SqlParameter("@day1", SqlDbType.VarChar, 10)); MyCommand.Parameters.Add(new SqlParameter("@clx_num", SqlDbType.TinyInt)); MyCommand.Parameters.Add(new SqlParameter("@clx_string", SqlDbType.VarChar, 10)); MyCommand.Parameters.Add(new SqlParameter("@ctime", SqlDbType.Int));
MyCommand.Parameters["@xqmess"].Direction = ParameterDirection.Output; MyCommand.Parameters["@cname"].Direction = ParameterDirection.Output; MyCommand.Parameters["@zy"].Direction = ParameterDirection.Output; MyCommand.Parameters["@nj"].Direction = ParameterDirection.Output; MyCommand.Parameters["@bname"].Direction = ParameterDirection.Output; MyCommand.Parameters["@tname"].Direction = ParameterDirection.Output; MyCommand.Parameters["@year1"].Direction = ParameterDirection.Output; MyCommand.Parameters["@month1"].Direction = ParameterDirection.Output; MyCommand.Parameters["@day1"].Direction = ParameterDirection.Output; MyCommand.Parameters["@clx_num"].Direction = ParameterDirection.Output; MyCommand.Parameters["@clx_string"].Direction = ParameterDirection.Output; MyCommand.Parameters["@ctime"].Direction = ParameterDirection.Output;
MyCommand.ExecuteNonQuery(); xqmess = Convert.ToString(MyCommand.Parameters["@xqmess"].Value); //接收输出的参数 cname = Convert.ToString(MyCommand.Parameters["@cname"].Value); zy = Convert.ToString(MyCommand.Parameters["@zy"].Value); nj = Convert.ToString(MyCommand.Parameters["@nj"].Value); bname = Convert.ToString(MyCommand.Parameters["@bname"].Value); tname = Convert.ToString(MyCommand.Parameters["@tname"].Value); year1 = Convert.ToString(MyCommand.Parameters["@year1"].Value); month1 = Convert.ToString(MyCommand.Parameters["@month1"].Value); day1 = Convert.ToString(MyCommand.Parameters["@day1"].Value); clx_num = Convert.ToInt16(MyCommand.Parameters["@clx_num"].Value); clx_string = Convert.ToString(MyCommand.Parameters["@clx_string"].Value); ctime = Convert.ToInt32(MyCommand.Parameters["@ctime"].Value); DB.close(); } |
该方法中引用的存储过程proc_fdpaper代码如下:
|
create proc proc_fdpaper --建立存储过程,显示改卷时候界面基本信息 @cno int, @bno int, @tno int, @xqmess varchar(100) output,--学期信息 @cname varchar(50) output, @zy varchar(40) output, @nj varchar(20) output, @bname varchar(30) output, @tname varchar(40) output, @year1 varchar(10) output, @month1 varchar(10) output, @day1 varchar(10) output, @clx_num tinyint output, @clx_string varchar(10) output, @ctime int output as
select @xqmess=SUBSTRING(skxq,1,4)+'-'+cast((CAST (SUBSTRING(skxq,1,4) AS int)+1) as varchar(10))+'学年第'+SUBSTRING(skxq,5,1)+'学期' from tc where cno=@cno and bno=@bno
select @tname=tname from teacher where tno=@tno
select @cname=cname,@clx_num=clx,@ctime=ctime from course where cno=@cno
set @clx_string= case when @clx_num=1 then '考查' when @clx_num=2 then '实习' when @clx_num=3 then '毕业论文' when @clx_num=4 then '毕业实习' else '考试' end
select @zy=zy,@nj=cast(year(btime) as varchar(20)),@bname=bname from class where bno=@bno
select @year1=cast(year(getdate()) as varchar(10)),@month1=cast(month(getdate()) as varchar(10)),@day1=cast(day(getdate()) as varchar(10))
GO |
浙公网安备 33010602011771号