SQL Schema 利用GridView 輸出資料表的欄位
相信很多公司,都需要出文件給客戶!
而文件基本上都會有資料庫DD或是相關文件要出。
這時候,如何快速的把Schema快速的抓取、設定呢!?
小弟公司也剛好遇到了這件事情,出自於自己好強心作祟,
從某個星期六晚上開始找資料,寫到凌晨三點,想去睡了!
結果,神經病又發作了!不停的寫,寫到了七點真的到一個段落才在睡夢中入睡。
以下紀錄一些關鍵語法,做法應該還有很多種!
畫面設計大概像上方一樣。
- 先說我設計的作用。
- 可以將主鍵用粉紅色顯示出來。
- 可以修改資料表欄位的描述欄位。(並非使用擴充屬性,直接設定MS_Description
- 該功能還有設計相關資料庫Select語法組成等,但由於公司部分,將不予以展示&說明。非常抱歉!
這樣的設定應該已經足夠用來產出文件了!
首先,當資料庫選取後,自動抓取該資料庫所擁有的資料表。
上方Table
1: <table align="center" border="1" cellpadding="0" cellspacing="0" class="table_95"
2: style="width: 60%;">
3: <tr>
4: <td class="table_item">
5: 請選擇資料庫
6: </td>
7: <td>
8: <asp:DropDownList ID="DDL_DB" runat="server" AutoPostBack="True" OnSelectedIndexChanged="DDL_DB_SelectedIndexChanged">
9: <asp:ListItem Text="預設資料庫" Value="Default"></asp:ListItem>
14: </asp:DropDownList>
15: </td>
16: <td class="table_item">
17: 請選擇資料表
18: </td>
19: <td>
20: <asp:DropDownList ID="DDL_Table" runat="server" DataTextField="name" DataValueField="name">
21: </asp:DropDownList>
22: </td>
23: </tr>
24: <tr>
25: <td colspan="4" align="center">
26: <asp:Button ID="btnSerch" runat="server" Text="查詢" OnClick="btnSerch_Click" />
27: </td>
28: </tr>
29: </table>
Gridview
1: <asp:GridView ID="gvTable" runat="server" AutoGenerateColumns="False" CssClass="table_100"
2: Width="60%" OnRowDataBound="gvTable_RowDataBound" OnRowCommand="gvTable_RowCommand">
3: <HeaderStyle CssClass="table_item" />
4: <RowStyle CssClass="table_content1" />
5: <AlternatingRowStyle CssClass="table_content2" />
6: <Columns>
7: <asp:TemplateField>
8: <HeaderTemplate>
9: <asp:CheckBox ID="CheckAll" runat="server" onclick="SelectAllCheckboxes(this);" onkeypress="SelectAllCheckboxes(this);"
10: Text="全選" ToolTip="按一次全選,再按一次取消全選" Checked="true" />
11: </HeaderTemplate>
12: <ItemTemplate>
13: <asp:CheckBox ID="cbxCheck" runat="server" Checked="true" />
14: </ItemTemplate>
15: <ItemStyle Width="10%" />
16: </asp:TemplateField>
17: <asp:BoundField DataField="ORDINAL_POSITION" HeaderText="順序" />
18: <asp:BoundField DataField="COLUMN_NAME" HeaderText="名稱" />
19: <asp:BoundField DataField="IsKey" HeaderText="主鍵" />
20: <asp:BoundField DataField="DATA_TYPE" HeaderText="類型" />
21: <asp:BoundField DataField="CHARACTER_MAXIMUM_LENGTH" HeaderText="長度" />
22: <asp:BoundField DataField="COLUMN_DEFAULT" HeaderText="預設值" />
23: <asp:BoundField DataField="IS_NULLABLE" HeaderText="空值" />
24: <asp:TemplateField HeaderText="欄位描述">
25: <ItemTemplate>
26: <asp:Label ID="lblNote" runat="server" Text='<%#Eval("value") %>'></asp:Label>
27: <asp:TextBox ID="tbxNote" runat="server" Text='<%#Eval("value") %>' Visible="false"
28: Width="95%" BorderStyle="Solid" BorderColor="Black" BorderWidth="1px"></asp:TextBox>
29: </ItemTemplate>
30: </asp:TemplateField>
31: <asp:TemplateField HeaderText="處理作業">
32: <ItemTemplate>
33: <asp:Button ID="btnUpdate" runat="server" CausesValidation="False" CommandArgument='<%# Eval("COLUMN_NAME") %>'
34: CommandName="UpdateDevice" Text="修改" Visible="true" />
35: <asp:Button ID="btnSave" runat="server" CausesValidation="False" CommandArgument='<%# Eval("COLUMN_NAME") %>'
36: CommandName="SaveDevice" Text="存檔" Visible="false" />
37: </ItemTemplate>
38: </asp:TemplateField>
39: </Columns>
40: </asp:GridView>
當然,這裡還利用了上一篇,gridview的checkbox的全選/取消功能。
所利用到的javascript
1: <script type="text/javascript">
2: function SelectAllCheckboxes(spanChk) {
3: elm = document.forms[0];
4: for (i = 0; i <= elm.length - 1; i++) {
5: if (elm[i].type == "checkbox" && elm[i].id != spanChk.id) {
6: if (elm.elements[i].checked != spanChk.checked)
7: elm.elements[i].click();
8: }
9: }
10: }
11: </script>
好啦~畫面設計差不多到這裡結束了!再來談談真正的關鍵吧!
首先按下查詢按鈕時,我們做以下動作:
我只記錄下了語法,至於Gridview的DataBinde()等不予描述!
查詢的SQL:
1: protected void GetGvDate()
2: {
3: SQLStr = "select L.ORDINAL_POSITION,(case L.IS_NULLABLE when 'No' then 'N' else 'Y' end )IS_NULLABLE, " +
4: " L.COLUMN_NAME,L.COLUMN_DEFAULT,L.DATA_TYPE,L.CHARACTER_MAXIMUM_LENGTH,L2.value,'' IsKey " +
5: " from information_schema.columns L" +
6: " left join " +
7: " (SELECT value,objname" +
8: " FROM ::fn_listextendedproperty(NULL, 'user', 'dbo', 'table', @TableName, 'column', default) )L2" +
9: " on L.COLUMN_NAME = L2.objname COLLATE Chinese_Taiwan_Stroke_CI_AS" +
10: " where L.table_name = @TableName ";
11: }
@TableName 將等於下拉選單所選的值"DDL_Table.SelectedValue"。
沒錯,就這麼簡單的,沒有意外我們的Gridview已經可以成功的抓取資料嚕!!
如果,急著執行的你出錯了,別緊張!因為我們還沒處理Gridview的RowCommand和RowDataBound。
還記得我剛剛有說主鍵會已粉紅色呈現吧!
我們在RowDataBound做這件事情,方法如下:
1: protected void gvTable_RowDataBound(object sender, GridViewRowEventArgs e)
2: {
3: if (e.Row.RowType == DataControlRowType.DataRow)
4: {
5: SQLStr = "Exec sp_pkeys @TN";
6: DataSet SDs = //執行完上方預存程序後回傳一個Dataset
7: foreach (DataRow aRow in SDs.Tables[0].Rows)
8: {
9: if (e.Row.Cells[2].Text == aRow["COLUMN_NAME"].ToString())
10: {
11: e.Row.Cells[3].Text = "Y";
12: e.Row.BackColor = System.Drawing.Color.Pink;
13: }
14: else { e.Row.Cells[3].Text = "N"; }
15: }
16: }
17: }
再來,我們要處理表格欄位描述修改的動作。
此一動作我們將在RowCommand中進行,程式碼如下:
1: protected void gvTable_RowCommand(object sender, GridViewCommandEventArgs e)
2: {
3: int rowIndex = ((GridViewRow)((Button)e.CommandSource).NamingContainer).RowIndex;//抓取該列的RowIndex
4: Label lblNote = (Label)gvTable.Rows[rowIndex].FindControl("lblNote");
5: TextBox tbxNote = (TextBox)gvTable.Rows[rowIndex].FindControl("tbxNote");
6: Button btnUpdate = (Button)gvTable.Rows[rowIndex].FindControl("btnUpdate");
7: Button btnSave = (Button)gvTable.Rows[rowIndex].FindControl("btnSave");
8: switch (e.CommandName)
9: {
10: case "UpdateDevice":
16: lblNote.Visible = false;
17: tbxNote.Visible = true;
18: btnSave.Visible = true;
19: btnUpdate.Visible = false;
20: break;
21: case "SaveDevice":
22: string ColmnName = gvTable.Rows[rowIndex].Cells[2].Text;
23: string TableName = DDL_Table.SelectedValue;
24:
25: SQLStr = " SELECT value,objname " +
26: " FROM ::fn_listextendedproperty(NULL, 'user', 'dbo', 'table', @TB, 'column', default)" +
27: " where objname = @CL";
28: //@TB=資料表
29: //@CL=欄位
30: DataSet tDS =//執行完上方的SQL得到的DataSet
31:
32: if (tDS.Tables[0].Rows.Count > 0)
33: {
34: SQLStr = "exec sp_updateextendedproperty @name=N'MS_Description', @value=@Rval, @level0type= N'Schema',@level0name=N'dbo'," +
35: "@level1type=N'TABLE', @level1name=@Rval2, @level2type=N'COLUMN', @level2name=@Rval3";
36: //請在此執行上述的SQLStr,請記得要傳參數給預存程式
37: //參數說明:@Rval = 描述 @Rval2 = 表格名稱 @Rval3 = 欄位名稱
38:
39: }
40: else
41: {
42: SQLStr = "exec sp_addextendedproperty @name=N'MS_Description', @value=@Rval, @level0type= N'Schema',@level0name=N'dbo'," +
43: "@level1type=N'TABLE', @level1name=@Rval2, @level2type=N'COLUMN', @level2name=@Rval3";
44: //請在此執行上述的SQLStr,請記得要傳參數給預存程式
45: //參數說明:@Rval = 描述 @Rval2 = 表格名稱 @Rval3 = 欄位名稱
46: }
47:
53: lblNote.Visible = true;
54: tbxNote.Visible = false;
55: btnSave.Visible = false;
56: btnUpdate.Visible = true;
57: break;
58: }
59: }
當我們按下修改按鈕時,將我們原本隱藏的Textbox和存檔的按鈕顯示出來。
在按下存檔案紐時,先抓取該欄位是否已經有針對該欄位描述過,若有則是更新,沒有則是使用新增。
存檔完再把一開始的欄位開始/關閉。
相關參考資源:
感謝以上的先賢門!讓我懂得進步!
也歡迎各位可以指出相關指教!或是給予我進步的空間!謝謝!