zoukankan      html  css  js  c++  java
  • 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目录为源码

  • 相关阅读:
    Activity 生命周期 返回键 退出 杂谈
    多线程基本语法
    常用代码
    JSP 相关
    powerDesiger uml class
    抽象类的说明
    javaScript 中常用的正则表达式
    chickbox 的使用
    对象在内存中的状态
    jQuery 常用代码
  • 原文地址:https://www.cnblogs.com/lzrabbit/p/2484878.html
Copyright © 2011-2022 走看看