摘 要: 為便于團隊交流與系統(tǒng)維護,在對表的設計結(jié)構(gòu)修改后,,應及時更新項目技術(shù)文檔,。為克服現(xiàn)有方法存在的不足,,在Visual Studio 2010環(huán)境下,,基于C#編程語言,開發(fā)了一個針對SQL Server數(shù)據(jù)庫表結(jié)構(gòu)的報表生成系統(tǒng),。該系統(tǒng)支持單表導出和批量導出兩種工作模式,,支持將表結(jié)構(gòu)導出到Word和Excel兩種應用接口,具有操作簡單,、使用靈活和功能完善的優(yōu)點,,對提高團隊開發(fā)效率和技術(shù)文檔的規(guī)范性具有一定的應用價值。
關(guān)鍵詞: SQL Server數(shù)據(jù)庫,;表設計結(jié)構(gòu),;報表生成
數(shù)據(jù)庫結(jié)構(gòu)設計主要包括需求分析、概念結(jié)構(gòu),、邏輯結(jié)構(gòu)和物理結(jié)構(gòu)設計等多個階段,,是一個反復探索、逐步求精的過程[1-2],。優(yōu)化存儲結(jié)構(gòu),、提高查詢效率,確保數(shù)據(jù)的準確性,、一致性與完整性,,在數(shù)據(jù)庫結(jié)構(gòu)設計時,需頻繁地對表結(jié)構(gòu)進行論證,、修訂和優(yōu)化[3-4],。為方便團隊交流與系統(tǒng)維護,表的邏輯結(jié)構(gòu)說明是數(shù)據(jù)庫項目技術(shù)文檔不可或缺的內(nèi)容,,因此在對表的設計結(jié)構(gòu)修改后,,應及時更新表設計結(jié)構(gòu)的說明文檔,其實現(xiàn)方法通常有兩種:一是借助數(shù)據(jù)庫設計工具(Rose,、Power Designer等)導出設計結(jié)構(gòu)報表,,該方法集成度高且生成技術(shù)文檔相對規(guī)范,,但在進入編碼開發(fā)階段后,再對表的邏輯結(jié)構(gòu)修訂完善,,往往只需對個別表設計結(jié)構(gòu)的小幅變更,,由于模板定制復雜且流程性過強,該方法的適用性與靈活性受到局限,。二是在表結(jié)構(gòu)修改后,,采用手工修訂的方法調(diào)整開發(fā)文檔中的相應內(nèi)容,該方法靈活性高,,但工作繁瑣,,且難以確保對表結(jié)構(gòu)描述的一致性[5-6]。
本文在Visual Studio 2010開發(fā)環(huán)境下,,利用C#編程語言,,針對SQL Server數(shù)據(jù)庫環(huán)境,開發(fā)了一個針對數(shù)據(jù)庫表結(jié)構(gòu)的報表生成系統(tǒng),。該系統(tǒng)支持兩種工作模式:即單表模式和批量模式,。顧名思義,在單表模式下,,用戶通過一次操作可導出某個指定表格的設計結(jié)構(gòu),;在批量模式下,系統(tǒng)支持一次導出數(shù)據(jù)庫中的全部或多個表格的結(jié)構(gòu)屬性,。同時,,系統(tǒng)提供了相應接口,用戶可根據(jù)需要將相應數(shù)據(jù)導出到Word或Excel文檔中,。限于篇幅,,本文主要通過單表工作模式,介紹該系統(tǒng)的功能結(jié)構(gòu),、實現(xiàn)方法及工作流程,。
1 系統(tǒng)實現(xiàn)
系統(tǒng)的用戶主界面如圖1所示,該系統(tǒng)主要包括數(shù)據(jù)庫連接模塊,、屬性選擇模塊,、設計結(jié)構(gòu)輸出模塊、數(shù)據(jù)導出模塊等4部分,。
1.1 數(shù)據(jù)庫連接模塊
數(shù)據(jù)庫連接模塊用于與數(shù)據(jù)庫建立連接,,讀取并輸出數(shù)據(jù)中包含的所有表的名稱。其中實現(xiàn)過程可描述為:(1)根據(jù)用戶輸入的服務器地址,、數(shù)據(jù)庫名稱,、用戶名及密碼,驗證其是否正確,,確保連接成功,;(2)在連接成功后,,讀取數(shù)據(jù)中所包含的表,當操作模式批量導出時,,輸出到CheckedListBox復選列表框,;當操作模式為單表導出時,輸出到下拉列表,,其關(guān)鍵代碼下:
cShowTableStructure sts=new cShowTableStructure(),;
sts.connStr=String.Format("server={0};database={1},;
uid={2},;pwd={3}",
serverName,,dBaseName,,userId,userPwd),;//連接字符串
sts.sqlStr=String.Format("select*from+{0}.dbo.sysobjects
where xtype=′U′
order by name asc",,dBaseName);//查詢語句
DataTable dtable=sts.mReadTableInfors(),;
//讀取數(shù)據(jù)庫中的表名,返回一個DataTable
if(dtable =null)
{
MessageBox.Show("連接成功,,請選擇表格,!");
//將表格名稱添加為下拉列表的Items
for(int i=0,;i<=dtable.Rows.Count-1,;i++)
{
string tName=dtable.Rows[i][0].ToString();
cmb_TableName.Items.Add(tName),;
cmb_TableName.SelectedIndex=0,;
}
btnChooseTable.Enabled=true;//允許用戶提交選擇項
}
else{……}
1.2 屬性選擇模塊
在用戶建立表的過程中,,數(shù)據(jù)庫管理系統(tǒng)將保存表設計結(jié)構(gòu)的信息,,包括字段名、數(shù)據(jù)類型,、長度,、默認值及字段說明等。為方便用戶進行選擇,,通過類型為CheckBox的數(shù)組ckBoxs,,呈現(xiàn)在表設計的常用屬性,供用戶選擇,。其中,,序號與字段名為必選項,,其他信息用戶根據(jù)需要進行選擇,默認為全選,。通過條件選擇語句對SQL查詢語句的組合,,實現(xiàn)對用戶所關(guān)心屬性的選擇性輸出,其關(guān)鍵代碼如下:
//根據(jù)用戶選擇的屬性,,控制SQL查詢的輸出字段
string sqlstr="Select",;
if(ckBoxs[0].Checked){sqlstr+="a.colorder N′序號′,",;}
if(ckBoxs[1].Checked){sqlstr+="a.name N′字段名′,,";}
if(ckBoxs[2].Checked){sqlstr+="(case when
COLUMNPROPERTY(a.id,,a.name,,
′IsIdentity′)=1 then′√¨?′else′′end)N′是否標識′,,",;}
…… ……
if(ckBoxs[9].Checked){sqlstr+="isnull(e.text,′′)N′默認值′,,",;}
if(ckBoxs[10].Checked){sqlstr+="isnull(g.[value],′′)AS N′字段說明′,,",;}
//去掉語句最后一個逗號,保證查詢語句的正確性
sqlstr=sqlstr.Remove(sqlstr.LastIndexOf(′,,′),,1);
1.3 表結(jié)構(gòu)輸出模塊
屬性選擇模塊實現(xiàn)對輸出字段與查詢條件的控制,,生成了相應的SQL查詢語句,。表設計結(jié)構(gòu)輸出模塊的任務是利用已有的查詢語句,訪問數(shù)據(jù)庫并讀取表設計信息,,然后輸出到用戶界面,,其關(guān)鍵代碼如下:
cShowTableStructure sts=new cShowTableStructure()
{sqlStr=sqlstr,connStr=connstr},;
DataTable dtable=new DataTable(),;
dtable=sts.mReadTableInfors();
if(dtable!=null)
{
dgv_TableStructure.DataSource=dtable,;
for(int i=1,;i<=dgv_TableStructure.Columns.Count-1;
i++)
{dgv_TableStructure.Columns[i].Width=80;}
//設置DataGridView列寬
}
其中,,SQL查詢語句sqlstr由屬性選擇模塊生成,,連接字符串connstr與數(shù)據(jù)庫連接模塊一致。因此,,該模塊的運行流程可描述為:(1)通過實例化cShowTableStructure類,,新建一個sts對象,設置連接字符串與查詢語句,;(2)調(diào)用mReadTableInfors方法,,讀取表結(jié)構(gòu)信息,以DataTable格式返回查詢結(jié)果,;(3)將查詢結(jié)果作為DataGridView控件的數(shù)據(jù)源,,輸出到用戶界面。
1.4 數(shù)據(jù)導出模塊
通過表設計結(jié)構(gòu)輸出模塊,,可以方便地獲取相應表所包含的字段及其屬性,,為了實現(xiàn)數(shù)據(jù)設計與文檔整理的同步,需要將DataGridView控件中的信息導出到Excel或word文檔中,,以便開發(fā)編寫開發(fā)文檔和團隊交流時使用,。系統(tǒng)提供了兩種應用接口,用戶可根據(jù)需要將表結(jié)構(gòu)輸出到Excel或word文檔,。限于篇幅,,本文僅介紹將表結(jié)構(gòu)導出到Excel文檔的實現(xiàn)方法,其關(guān)鍵代碼如下:
//新建一個Excel應用,,設置屬性與文檔名
Excel.Application texcel=new Excel.Application(),;
texcel.Application.Workbooks.Add(true);
texcel.Visible=isShowExcel,;
texcel.SaveWorkspace(TableName+"表的結(jié)構(gòu)");
int co_count=dgv_TableStructure.Columns.Count,;
int row_count=dgv_TableStructure.Rows.Count,;
//第一行合并單元格,輸出表名
string Title_End=endChar+"1",;
texcel.Cells.get_Range("A1",,Title_End).MergeCells=true;
texcel.Cells[1,,1]=TableName+"表的設計結(jié)構(gòu)",;
//第二行輸出相應的字段名
for(int i=0;i<=co_count-1,;i++)
{texcel.Cells[2,,i+1]=dgv_TableStructure.Columns[i].
HeaderText;}
//從第三行開始,輸出表的結(jié)構(gòu)信息
for(int i=0,;i<row_count-1,;i++){
for(int j=0;j<=co_count-1,;j++){
if(dgv_TableStructure[j,,i].ValueType==typeof
(string))
texcel.Cells[i+3,j+1]=""+dgv_TableStructure[j,,i].
Value,;
else
texcel.Cells[i+3,j+1]=dgv_TableStructure[j,,i].
Value.ToString(),;
}
}
//設置Excel有效數(shù)據(jù)區(qū)域的格式
char endChar=Convert.ToChar(′A′+co_count-1);
…… ……
content_range.Borders.LineStyle=BorderStyle.FixedSingle,;
因此,,該模塊的工作流程可描述為:(1)新建一個Excel應用,設置相關(guān)屬性,;(2)計算輸出到有效數(shù)據(jù)的行,、列數(shù),在第一行輸出表名稱,;(3)將DataGridView控件表頭文本作為字段名,,輸出到第二行;(4)從第三行開始,,逐單元格輸出對應信息,;(4)選擇Excel中的數(shù)據(jù)區(qū)域,設置其邊框,、字體等格式樣式,。
1.5 關(guān)鍵類cShowTableStructure實現(xiàn)
在1.1節(jié)數(shù)據(jù)庫連接模塊與1.3節(jié)表設計結(jié)構(gòu)輸出模塊中,都用到了一個名為cShowTableStructure的類,,該類的主要功能是實現(xiàn)對數(shù)據(jù)庫的查詢,,并將查詢結(jié)果通過一個DataTable返回。cShowTableStructure類封裝了兩個屬性(SQL查詢語句sqlStr與連接字符串connStr)及一個方法mReadTableInfors,,mReadTableInfors的關(guān)鍵代碼如下:
SqlConnection conn=new SqlConnection(connstr),;
SqlCommand cmd=new SqlCommand(sqlstr,conn),;
DataTable dtable=new DataTable(),;
SqlDataAdapter sda=new SqlDataAdapter();
try
{ conn.Open(),;
sda=new SqlDataAdapter(cmd),;
sda.Fill(dtable);
}
catch(Exception x)
{ …… //異常處理}
Finally
{ …… //資源釋放}
return dtable;
2 業(yè)務流程圖
系統(tǒng)的業(yè)務流程如圖2所示,,該流程可描述為:(1)選擇操作模式(單表導出或批量導出),;(2)用戶輸入數(shù)據(jù)庫服務器地址(名稱)、數(shù)據(jù)庫名,、用戶名和密碼,;(3)系統(tǒng)驗證數(shù)據(jù)庫所提交信息的正確性,若通過驗證,,則轉(zhuǎn)第(4)步,,否則轉(zhuǎn)第(2)步;(4)讀取數(shù)據(jù)庫包含的所有表格,,將表名輸出到用戶界面,,用戶選擇并提交所選表格;(5)選擇對所選表需查看,、輸出的結(jié)構(gòu)屬性,;(6)提交查詢,在用戶界面顯示查詢結(jié)果,;(7)選擇導出方式,,將表的設計結(jié)構(gòu)導出到Word或Excel文檔。
數(shù)據(jù)庫設計是項目開發(fā)的一項重要內(nèi)容,,在數(shù)據(jù)庫設計階段,,開發(fā)團隊需就其表結(jié)構(gòu)反復地進行論證、修訂與完善,;進入編碼階段后,,盡管不鼓勵對數(shù)據(jù)庫結(jié)構(gòu)再進行修改,但小幅度的調(diào)整與優(yōu)化往往難以杜絕,。為方便團隊協(xié)作與后期維護,,在對數(shù)據(jù)庫結(jié)構(gòu)調(diào)整后,及時更新項目開發(fā)文檔顯得尤為重要,。但在對數(shù)據(jù)庫結(jié)構(gòu)改動后,,手工調(diào)整或借助第三方工具重新生成說明文檔,工作繁復且難以確保對表結(jié)構(gòu)描述的一致性,。針對這一需求,本文開發(fā)了一個數(shù)據(jù)庫表結(jié)構(gòu)自動導出系統(tǒng),,以方便用戶根據(jù)需要導出表的結(jié)構(gòu)信息,,具有小巧便捷、操作簡單的優(yōu)點,,將其作為團隊開發(fā)的輔助工具,,能較大幅度提高工作效率。
參考文獻
[1] 何玉潔.數(shù)據(jù)庫原理與實踐教程[M].北京:清華大學出版社,2010.
[2] 王征,,呂雷.SQL Server 2008中文版數(shù)據(jù)庫基礎與實踐教程[M].北京:電子工業(yè)出版社,,2009.
[3] 李偉.數(shù)據(jù)完整性在數(shù)據(jù)庫應用系統(tǒng)的設計與實施[J].煤炭技術(shù),2011,,30(3):167-168.
[4] 朱曉輝,,王杰華,石振國,,等..NET下基于PowerDesigner和CodeSmith的軟件自動化開發(fā)技術(shù)[J].計算機科學,,2010,37(7):156-160.
[5] 謝星星,,沈懿卓.UML基礎與Rose建模實用教程[M].北京:清華大學出版社,,2008.
[6] 張慶輝,邵易峰.基于Power Designer的通信裝備數(shù)據(jù)庫設計實現(xiàn)[J].艦船電子工程,,2012(2):68-70.