65.9K
CodeProject 正在变化。 阅读更多。
Home

一个用于 MSSQL 2000 & 2005、MySQL 5.0 等的 SQL 管理控制台。

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.86/5 (11投票s)

2008年4月20日

Ms-PL

4分钟阅读

viewsIcon

70622

downloadIcon

2548

一篇关于适用于不同类型 RDBMS 数据库的 SQL IDE 的文章。

SQLManagementConsole/sqlmgtconsole_mssql2005.jpg

引言

由于 MSSQL 尚未占据市场的主导地位,因此与 PL/Oracle、MySQLFireBird、DB2 等其他 RDBMS 的集成/交互是不可避免的。通过 ADO .NET 2.0 中的 System.Data.Common 类,不同的数据提供者可以编写程序集,以便 .NET 应用程序可以轻松地与它们通信,他们称之为 连接器

背景

当我第一次参与一个需要与 MySQL、FireBird、Oracle、OleDB、ODBC 等接口的项目时,我完全不知所措。有太多了。这就像过去不同的厂商在操作系统大战、C++ IDE 大战中争夺市场份额一样。 Borland C++ 是我的第一个编程 IDE,现在它已经被淘汰了。这些战争都已成为历史,但数据库战争仍在继续。

对于每个数据提供者,厂商都会提供 GUI 查询控制台供用户进行可视化数据交互。虽然其中大多数都是免费的,但舒适地使用它们仍然是另一个问题。从我个人的观点来看(请不要在评论中与我争论,这只是我的观点),SSMS(包括 Express Ed.)是所有管理控制台中最好的(我一直在使用 MySQL Query Browser 和一个类似 InterBase 的 FireBird 查询浏览器,尽管可能不会持续很久)。

创建此程序的目的是什么?哈哈,和其他开发者一样:我觉得没有其他工具能满足我的需求,所以我就自己创建了。开玩笑。:) 主要目的是为 MSSQL 用户准备一个熟悉的 IDE/管理控制台,以适应不同的数据库。我希望有一天,我的应用程序能与 Red-GatemyLittleAdmin 等工具相媲美。

特点

此版本包含的功能有:

  1. (IDE 功能)打开/保存/拖放
  2. (IDE 功能)查询窗格和结果窗格
  3. (MS SQL 2000 & 2005)系统对象浏览器(标量函数、存储过程、系统表、表函数、触发器、用户表、视图)
  4. (MS SQL 2000 & 2005)安全对象浏览器(用户、角色、架构)
  5. (MS SQL 2000 & 2005)约束、列、参数对象浏览器(列、键、约束、触发器、索引、参数)
  6. (MS SQL 2000 & 2005)对象依赖项查看器(标量函数、存储过程、系统表、表函数、触发器、用户表、视图)
  7. (MS SQL 2000 & 2005)非加密对象的对象脚本(标量函数、存储过程、表函数、触发器、视图)
  8. (MySQL 5.0)系统对象浏览器(标量函数、存储过程、系统表、触发器、用户表、视图)
  9. (MySQL 5.0)安全对象浏览器(用户、权限)
  10. (MySQL 5.0)约束、列对象浏览器(列、键、触发器)
  11. (MySQL 5.0)非加密对象的对象脚本(标量函数、存储过程、触发器、视图)

SQLManagementConsole/sqlmgtconsole_mysql5.jpg

SQLManagementConsole/dependency.jpg

SQLManagementConsole/scripting.jpg

Using the Code

通过使用数据库中的 信息架构视图,您可以轻松地浏览 MS SQL 中的任何对象。(看起来微软有额外的处理方式,所以我实现的可能与 SSMS 不是 100% 匹配;风险自负)。另一种方法是通过 系统表。微软使用系统表来处理 SSMS 中的系统存储过程,您甚至可以打开(在 SSMS 中,位于对象资源管理器:可编程性 > 存储过程 > 系统存储过程)并查看其工作原理。

为了将多种类型的 RDBMS 数据库集成到一个 IDE 中,使用了 接口 类,这样每种类型的数据库都与其他数据库完全封装,但它们仍然具有 IDE 的通用签名。

SQLManagementConsole/login.jpg

在收集用户输入(或从app.config 文件读取)后,将构造连接字符串和类名等有用信息,并用于接口初始化。

    private void fnFindWindows(string strDBType, string strConnString, string strDataProvider)
        {
            // Clear out the collection
            _toolWindows.Clear();

            // Use reflection to look for types
            foreach (Type t in Assembly.GetExecutingAssembly().GetTypes())
            {
                if (t.GetInterface("IToolWindow") != null)
                {
                    // load one database type per each session
                    if(t.Name.ToUpper().Equals(strDBType.ToUpper()))
                    {
                        // Try the empty constructor
                        if (t.GetConstructor(new Type[0]) != null)
                        {
                            _toolWindows.Add((IToolWindow)Activator.CreateInstance(t));
                        }
                        else
                        {
                            _toolWindows.Add((IToolWindow)Activator.CreateInstance(t, new object[] 
                                  { this.rtbQueryConsole, this.tscbDBList, 
                                    strConnString, strDataProvider }));
                        }
                    }
                }
            }

            // Add toolwindows to each ToolWindowHost
            foreach (Control c in this.Controls)
            {
                ToolWindowHost host = c as ToolWindowHost;
                if (host != null)
                {
                    foreach (IToolWindow tw in _toolWindows)
                    {
                        host.AddToolWindow(tw);
                        host.ShowToolWindow(tw);
                        host.Dock = DockStyle.Left;
                    }
                }
            }
        }

在构造 MSSQL 对象浏览器时,您需要类似这样的内容:

    private void fnChannelSysObj(TreeNode tnBaseNode, bool bRefresh)
        {
            string strXType = "";
            switch (tnBaseNode.Text)
            {
                // Need qualified name; New database in MSSQL 2005 needs to use "INFORMATION_SCHEMA"
                case SYSOBJ_USRTBL:
                    // ms-help://MS.MSDNQTR.v80.en/MS.MSDN.v80/MS.SQL.v2000.en/tsqlref/ts_ia-iz_56lv.htm
                    fnAddSysObj_SysCol(tnBaseNode, tnBaseNode.Parent.Text, bRefresh,
                                        "Select * from INFORMATION_SCHEMA.TABLES ",
                                        new string[] { "TABLE_SCHEMA", "TABLE_NAME" },
                                        IconType.SysObject, false);
                    break;
                case SYSOBJ_VIEW:
                ...
                //----------------------------------------------------------------
                case SYSOBJ_FUNC:
                    strXType = "'FN'";
                    break;
                ...
                //----------------------------------------------------------------
                case SECURITY_USER:
                    // ms-help://MS.MSDNQTR.v80.en/MS.MSDN.v80/MS.SQL.v2005.en/tsqlref9/html/
                    // 5f0e6a8d-c983-44f6-97e9-aab5bff67d18.htm
                    fnAddSysObj_SysCol(tnBaseNode, tnBaseNode.Parent.Text, bRefresh,
                                        "Select * from dbo.sysusers"
                                        + " where isntuser = 1 or issqluser = 1",
                                        new string[] { "name" }, IconType.SysObject, true);
                    break;
                ...
                case SECURITY_SCHE:
                    // ms-help://MS.MSDNQTR.v80.en/MS.MSDN.v80/MS.SQL.v2005.en/tsqlref9/html/
                    // 69617642-0f54-4b25-b62f-5f39c8909601.htm
                    fnAddSysObj_SysCol(tnBaseNode, tnBaseNode.Parent.Text, bRefresh,
                                        "Select * from INFORMATION_SCHEMA.SCHEMATA"
                                        + " where CATALOG_NAME = '" + tnBaseNode.Parent.Text + "'",
                                        new string[] { "SCHEMA_NAME" }, IconType.SysObject, true);
                    break;
                default:
                    break;
            }

            if (!strXType.Trim().Equals(""))
            {
                // use qualified name; use "dbo.sysobjects" 
                // instead of "sys.sysobjects" for backward compatibility
                // ms-help://MS.MSDNQTR.v80.en/MS.MSDN.v80/MS.SQL.v2005.en/tsqlref9/html/
                // 44fdc387-67b0-4139-8bf5-ed26cf640cd1.htm
                fnAddSysObj_SysCol(tnBaseNode, tnBaseNode.Parent.Text, bRefresh,
                                    "Select name from dbo.sysobjects"
                                    + " WHERE xtype in (" + strXType + ") order by name",
                                    new string[] { "name" }, IconType.SysObject, false);
            }
        }

在构造 MySQL 对象浏览器时,您需要类似这样的内容:

    private void fnChannelSysObj(TreeNode tnBaseNode, bool bRefresh)
        {
            switch (tnBaseNode.Text)
            {
                case SYSOBJ_USRTBL:
                    fnAddSysObj_SysCol(tnBaseNode, tnBaseNode.Parent.Text, bRefresh,
                                        "Select * from INFORMATION_SCHEMA.TABLES " +
                                        " where Table_Schema = '" + tnBaseNode.Parent.Text + 
                                        "' and Table_Type in ('Base Table')",
                                        new string[] { "TABLE_NAME" },
                                        IconType.SysObject, false);
                    break;
                ...
                //----------------------------------------------------------------
                case SYSOBJ_FUNC:
                    fnAddSysObj_SysCol(tnBaseNode, tnBaseNode.Parent.Text, bRefresh,
                                        "Select * from INFORMATION_SCHEMA.ROUTINES " +
                                        " where ROUTINE_Schema = '" + tnBaseNode.Parent.Text + 
                                        "' and ROUTINE_Type = 'FUNCTION'",
                                        new string[] { "SPECIFIC_NAME" },
                                        IconType.SysObject, false);
                    break;
                ...
                case SYSOBJ_SYSTBL:
                    fnAddSysObj_SysCol(tnBaseNode, tnBaseNode.Parent.Text, bRefresh,
                                        "Select * from INFORMATION_SCHEMA.TABLES " +
                                        " where Table_Schema = '" + tnBaseNode.Parent.Text + 
                                        "' and Table_Type in ('SYSTEM VIEW')",
                                        new string[] { "TABLE_NAME" },
                                        IconType.SysObject, false);
                    break;
                //case SYSOBJ_TBLFUNC:
                //    strXType = "'TF'";
                //    break;
                case SYSOBJ_TRIG:
                    fnAddSysObj_SysCol(tnBaseNode, tnBaseNode.Parent.Text, bRefresh,
                                        "Select * from INFORMATION_SCHEMA.TRIGGERS " +
                                        " where TRIGGER_Schema = '" + tnBaseNode.Parent.Text + "' ",
                                        new string[] { "TRIGGER_NAME" },
                                        IconType.SysObject, false);
                    break;
                //----------------------------------------------------------------
                case SECURITY_USER:
                    // assume root user have the access of all tables
                    fnAddSysObj_SysCol(tnBaseNode, tnBaseNode.Parent.Text, bRefresh,
                                        "Select GRANTEE from INFORMATION_SCHEMA.SCHEMA_PRIVILEGES " +
                                        "where TABLE_SCHEMA = '" + tnBaseNode.Parent.Text + "' " +
                                        "group by GRANTEE " +
                                        "UNION " +
                                        "SELECT CONCAT('''', usr.User, _
                                        '''@''',  usr.Host, '''') as GRANTEE " +
                                        "FROM mysql.user usr where User = 'root'",
                                        new string[] { "GRANTEE" }, IconType.SysObject, false);
                    break;
                default:
                    break;
            }
        }

剩下的工作就是普通的 Windows 编程,您将在一个 IDE 中获得所有数据提供者。很棒,不是吗?

关注点

很多!与 Oracle、PostgreSQL 等的集成、时间戳数据类型异常、位数据类型显示为复选框、执行计划、sproc & 函数解密、数据库比较等等。这就是为什么这个版本是 0.1。

由于我不是数据库专家,任何建设性的评论和建议都欢迎!

您也可以随时从我的 博客 获取最新版本。

历史

  • 2008-04-21:发布 0.1 版本
© . All rights reserved.