Sql Server表結構及索引查詢器


  因經常需要處理大數量的表,因此查看表結構、數據量、以及索引情況基本上成為了常態,無奈生產環境的數據庫不讓我們直接訪問,因此想要了解到生產環境的數據庫的表結構和索引信息變得很麻煩需要經常找DBA幫忙找,而想查看具體某個表的數據量使用 select count(1) from table方法的效率實在慢的無法忍受,正所謂求人不如求己,花了點時間自己做了個查看數據庫表結構和索引的小工具順便溫習了下系統表一舉兩得,喜歡的朋友可以拿去用用。

工具功能很簡單但勝在實用(尤其是不讓開發人員用企業管理連接生產環境數據庫時,簡直是一大殺器),可以提高不少效率
  1.根據鏈接字符串列出服務器上所有的數據庫以及表。
  2.查看表的記錄數、字段及索引(包含覆蓋索引)信息。

默認界面如下

根據需要修改好數據連接串,點擊 鏈接 自動查詢出數據庫信息

雙擊數據庫加載所有的表並讀取表的記錄數(表名后面括號里的數字代表記錄數)

雙擊表名稱加載表的結構和索引信息

這里對列表字段做個簡單翻譯,以幫助英語不好的童鞋
 

表結構
ColumnName ColumnType ByteLength CharLength Scale IsIdentity IsNullable Remark
字段名稱 字段類型 字節長度 字符長度 小數位數 是否自增列 是否允許空 字段說明

  

表索引
 IndexName  IndexType  IsPrimaryKey  IsUnique  IsUniqueConstraint  IndexColumns IndexIncludeColumns 
 索引名稱  索引類型  是否主鍵  是否唯一  是否唯一約束  索引包含的列  覆蓋索引包含的列

 

  表結構里的Remark字段說明就是我們給列加的那個列說明,ByteLength是字段的字節長度,CharLength是字符長度,這兩個主要是針對nchar,nvarchar類型的在數據庫中比如定義 Name nvarchar(50),顯示的字節長度是100,字符長度才是50(nvarchar一個字符占兩個字節),不注意的話會很慘,曾經被這個玩意給害死(喜歡使用alt+F1 查看表結構信息,這時nvarchar(50)的字段類型會顯示長度為 100)

  表索引里面IndexColumns表示索引所包含的列,IndexIncludeColumns表示覆蓋索引所包含的列,比如:索引IX_Test1,IndexColumns為Name,Email,IndexIncludeColumns為Address,PostCode,覆蓋索引只能建立在非聚簇索引上,主要是為了解決書簽查找(RID、鍵查找),聚簇索引不存在書簽查找所以不能創建覆蓋索引,在此不再詳述  

create index IX_Test1 on Users(Name,Email) include(Address,PostCode)

恩,功能就這么簡單,利用好了能在工作中省下不少事情,貼一下主要代碼

SqlQuery.cs
public static class SqlQuery
    {

        public static List<string> GetDatabases(string connString)
        {
            string sql = "select name from sys.databases where name not in ('master','model','msdb','tempdb')";
            DataTable dt = DbHelperSQL.GetDataTable(connString, sql);
            return dt.Rows.Cast<DataRow>().Select(row => row["name"].ToString()).ToList();
        }

        public static Dictionary<string, string> GetTables(string connString, string database)
        {
            string sql = string.Format(@"select
                                        objects.name+'('+ltrim(str(rows))+')' showname,
                                        objects.name                                        
                                        from {0}.sys.objects 
                                        inner join {0}.dbo.sysindexes on objects.object_id=sysindexes.id and sysindexes.indid<=1
                                        where type='U' 
                                        order by objects.name", database);
            DataTable dt = DbHelperSQL.GetDataTable(connString.Replace("master", database), sql);
            return dt.Rows.Cast<DataRow>().ToDictionary(row => row["showname"].ToString(), row => row["name"].ToString());
        }

        public static DataTable GetColumns(string connString, string database, string tableName)
        {
            string sql = string.Format(@"select
                                        columns.name ColumnName,
                                        types.name ColumnType,
                                        columns.is_identity IsIdentity,
                                        columns.is_nullable IsNullable,
                                        cast(columns.max_length as int) ByteLength,
                                        (
                                            case 
                                                when types.name='nvarchar' and columns.max_length>0 then columns.max_length/2 
                                                when types.name='nchar' and columns.max_length>0 then columns.max_length/2
                                                when types.name='ntext' and columns.max_length>0 then columns.max_length/2 
                                                else columns.max_length
                                            end
                                        ) CharLength,
                                        cast(columns.scale as int) Scale,
                                        extended_properties.value Remark
                                        from {0}.sys.columns
                                        inner join {0}.sys.types on columns.system_type_id=types.system_type_id and columns.user_type_id=types.user_type_id
                                        left join {0}.sys.extended_properties on columns.object_id=extended_properties.major_id and columns.column_id=extended_properties.minor_id
                                        where object_id=OBJECT_ID(@tableName)
                                        order by columns.column_id", database);
            SqlParameter param = new SqlParameter("@tableName", SqlDbType.NVarChar, 100) { Value = database + ".dbo." + tableName };
            DataTable dt = DbHelperSQL.GetDataTable(connString, sql, param);
            return dt;
        }

        public static DataTable GetIndexs(string connString, string database, string tableName)
        {
            #region SQL
            string sql = string.Format(@"with IndexCTE as
                                        (
                                            select 
                                            indexes.object_id,
                                            indexes.index_id,
                                            indexes.name IndexName,
                                            indexes.type_desc IndexType,
                                            indexes.is_primary_key IsPrimaryKey,
                                            indexes.is_unique IsUnique,
                                            indexes.is_unique_constraint IsUniqueConstraint
                                            from {0}.sys.indexes
                                            where object_id =OBJECT_ID(@tableName)
                                        )
                                        ,IndexColumnTempCTE as
                                        (
                                            select 
                                            ic.object_id,
                                            ic.index_id,
                                            ic.column_id,
                                            ic.index_column_id,
                                            ic.is_included_column,
                                            cast(c.name as nvarchar(max)) columnname,
                                            CAST(null as nvarchar(max)) includekey
                                            from {0}.sys.index_columns ic
                                            inner join {0}.sys.columns c on ic.column_id=c.column_id and ic.object_id=c.object_id
                                            where ic.index_column_id=1 and ic.object_id =OBJECT_ID(@tableName)
                                            union all
                                            select
                                            ic.object_id,
                                            ic.index_id,
                                            ic.column_id,
                                            ic.index_column_id,
                                            ic.is_included_column, 
                                            case ic.is_included_column when 0 then columnname+','+c.name end,
                                            case 
                                            when ic.is_included_column = 1 and includekey is null then c.name
                                            when ic.is_included_column = 1 and includekey is not null then includekey+','+c.name
                                            end
                                            from {0}.sys.index_columns ic
                                            inner join IndexColumnTempCTE cte on cte.index_id=ic.index_id and cte.index_column_id+1=ic.index_column_id and cte.object_id=ic.object_id
                                            inner join {0}.sys.columns c on ic.column_id=c.column_id and ic.object_id=c.object_id
                                        ),
                                        IndexColumnCTE as
                                        (
                                            select
                                            object_id,
                                            index_id,
                                            max(columnname) IndexColumns,
                                            max(includekey) IndexIncludeColumns
                                            from IndexColumnTempCTE
                                            group by object_id,index_id
                                        )
                                        select 
                                        IndexCTE.IndexName,
                                         IndexCTE.IndexType,
                                         IndexCTE.IsPrimaryKey,
                                         IndexCTE.IsUnique,
                                         IndexCTE.IsUniqueConstraint,
                                        IndexColumnCTE.IndexColumns,
                                        IndexColumnCTE.IndexIncludeColumns
                                        from IndexCTE
                                        inner join IndexColumnCTE on IndexCTE.object_id=IndexColumnCTE.object_id and IndexCTE.index_id=IndexColumnCTE.index_id
                                        order by IndexCTE.object_id", database);
            #endregion
            SqlParameter param = new SqlParameter("@tableName", SqlDbType.NVarChar, 100) { Value = database + ".dbo." + tableName };
            return DbHelperSQL.GetDataTable(connString, sql, param);
        }
    }
Form1.cs
public partial class Form1 : Form
    {

        public Form1()
        {
            InitializeComponent();
        }

        private void btnConn_Click(object sender, EventArgs e)
        {
            try
            {
                string connString = this.txtConnString.Text;
                List<string> list = SqlQuery.GetDatabases(connString);
                this.treeView1.Nodes.Clear();
                this.treeView1.Nodes.AddRange(list.Select(item => new TreeNode { Text = item }).ToArray());
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.GetBaseException().Message, "系統異常", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void treeView1_DoubleClick(object sender, EventArgs e)
        {
            try
            {
                string connString = this.txtConnString.Text;
                TreeNode node = this.treeView1.SelectedNode;

                switch (node.Level)
                {
                    case 0:
                        node.Nodes.Clear();
                        node.Nodes.AddRange(SqlQuery.GetTables(connString, node.Text).Select(kv => new TreeNode { Text = kv.Key, Tag = kv.Value }).ToArray());
                        node.Expand();
                        break;
                    case 1:
                        this.gridColumns.DataSource = SqlQuery.GetColumns(connString, node.Parent.Text, node.Tag.ToString());
                        this.gridIndexs.DataSource = SqlQuery.GetIndexs(connString, node.Parent.Text, node.Tag.ToString());
                        break;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.GetBaseException().Message, "系統異常", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
    }

 

附上源碼下載:SqlQueryAnalyzer.rar

release目錄下為已經編譯好的程序SqlQueryAnalyzer.exe可以直接打開使用,src目錄為源碼


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM