【MS SQL】SQL Schema 利用GridView 輸出資料表的欄位

SQL Schema 利用GridView 輸出資料表的欄位

相信很多公司,都需要出文件給客戶!

而文件基本上都會有資料庫DD或是相關文件要出。

這時候,如何快速的把Schema快速的抓取、設定呢!?

小弟公司也剛好遇到了這件事情,出自於自己好強心作祟,

從某個星期六晚上開始找資料,寫到凌晨三點,想去睡了!

結果,神經病又發作了!不停的寫,寫到了七點真的到一個段落才在睡夢中入睡。

以下紀錄一些關鍵語法,做法應該還有很多種!

2011-04-15_234441

畫面設計大概像上方一樣。

  • 先說我設計的作用。
  • 可以將主鍵用粉紅色顯示出來。
  • 可以修改資料表欄位的描述欄位。(並非使用擴充屬性,直接設定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和存檔的按鈕顯示出來。

在按下存檔案紐時,先抓取該欄位是否已經有針對該欄位描述過,若有則是更新,沒有則是使用新增。

存檔完再把一開始的欄位開始/關閉。

相關參考資源:

保哥的技術論壇

微軟針對描述的說明

Johnny.Net

topcat 姍舞之間的極度凝聚

 

感謝以上的先賢門!讓我懂得進步!

也歡迎各位可以指出相關指教!或是給予我進步的空間!謝謝!