【ITOO 2】.NET 动态建库建表:使用SQL字符串拼接方式

导读:在最近接手的项目(高效云平台)中,有一个需求是要当企业用户注册时,给其动态的新建一个库和表。刚开始接手的时候,是一点头绪都没有,然后查了一些资料,也问了问上一版本的师哥师姐,终于有了点头绪。目前是有两种方案,第一:应用SQL字符串拼接;第二,使用codeFirst。现在,总结第一种方案。


一、总体概述

既然是使用SQL字符串拼接,那么就涉及到我们操作SQL 创建数据库和表的逻辑了。当我们建库的时候,需要判断这个库是否存在,然后是不存在则创建。同理,建表也是如此。所以,在这里就涉及到了4个方法:1,判断欲建的数据库是否存在;2,判断欲建的表单是否存在;3,建库;4,建表。

在写好了这四个方法之后,就是对于方法的调用。


二、具体代码实例

2.1,判断数据库是否存在

<span style="font-family:KaiTi_GB2312;font-size:18px;">/// <summary>
        /// 是否存在将要创建的数据库
        /// </summary>
        /// <param name="strDatabaseName">数据库名称</param>
        /// <param name="strDbIP">数据库服务器连接地址</param>
        /// <returns>存在返回true,不存在返回false</returns>
        private bool isExsitDatabase(string strDatabaseName,string strDbIP) 
        {
            SqlConnection conn = new SqlConnection(strDbIP);
            conn.Open();
            string strSql = " select * from master.dbo.sysdatabases where name " + "= '" + strDatabaseName + "'"; ;
            SqlCommand cmd=new SqlCommand(strSql,conn);
            SqlDataReader sdr = null;
            DataTable dt = new DataTable();
            using (sdr=cmd.ExecuteReader(CommandBehavior.CloseConnection))
            {
                dt.Load(sdr);
            }
            if (dt.Rows.Count > 0)
            {
                return true;
            }
            else {
                return false;
            }
        }</span>

2.2,判断表单是否存在

<span style="font-family:KaiTi_GB2312;font-size:18px;">  /// <summary>
        /// 是否存在欲要建立的表单
        /// </summary>
        /// <param name="StrDatabaseName">数据库名称</param>
        /// <param name="strDbIP">数据库服务器连接地址</param>
        /// <param name="strTableName">将要建立的表单名称</param>
        /// <returns>存在返回true,不存在返回false</returns>
        private bool isExsitTable(string StrDatabaseName, string strDbIP, string strTableName) {
            SqlConnection conn = new SqlConnection(strDbIP);
            conn.Open();
            string strSQL = "use " + StrDatabaseName + " select 1 from sysobjects where id = object_id('" + strTableName + "') and type ='U'";
            SqlCommand cmd = new SqlCommand(strSQL, conn);
            int res = cmd.ExecuteNonQuery();
            DataTable dt = new DataTable();
            SqlDataReader sdr = null;
            using (sdr=cmd.ExecuteReader(CommandBehavior.CloseConnection))
            {
                dt.Load(sdr);
            }
            if (dt.Rows.Count > 0)
            {
                return true;
            }
            else {
                return false;
            }
        }</span>


2.3,建库

<span style="font-family:KaiTi_GB2312;font-size:18px;"> /// <summary>
        /// 创建一个新库
        /// </summary>
        /// <param name="strDatabaseName">数据库名称</param>
        /// <param name="strDbIP">数据库连接地址</param>
        private void CreateDatabase(string strDatabaseName, string strDbIP) {
            bool flag = isExsitDatabase(strDatabaseName, strDbIP);
            if (flag == true)
            {
                throw new Exception("当前数据库已经存在,无法重复创建");
            }
            else
            {
                string strSQL = "Create database " + strDatabaseName;
                SqlConnection conn = new SqlConnection(strDbIP);
                conn.Open();
                SqlCommand cmd = new SqlCommand(strSQL, conn);
                cmd.ExecuteNonQuery();
                conn.Close();

            }
        }</span>


2.4,建表

<span style="font-family:KaiTi_GB2312;font-size:18px;">/// <summary>
        /// 在指定的数据库中创建表单
        /// </summary>
        /// <param name="strDatabaseName">数据库名称</param>
        /// <param name="strDbIP">数据库连接地址</param>
        /// <param name="strTableName">表单名称</param>
        /// <param name="dic">表单内容</param>
        private void CreateTable(string strDatabaseName, string strDbIP, string strTableName,Dictionary<string ,string >dic) {
            bool flag = isExsitDatabase(strDatabaseName, strDbIP);
            if (flag == false)
            {
                throw new Exception("当前数据库不存在存在,请先创建数据库");
            }
            if (isExsitTable(strDatabaseName,strDbIP,strTableName)==true)
            {
                throw new Exception("当前表单已经存在,请修改!");
            }
            else
            {
                string content = "serial int identity(1,1) primary key";
                //取出dic中的内容,进行拼接
                List<string> test = new List<string>(dic.Keys);
                for (int i = 0; i < dic.Count(); i++)
                {
                    content = content + "," + test[i] + "" + dic[test[i]];
                }

                //其后判断数据库表是否存在,然创建表
                string strSQL = "use " + strDatabaseName + " create table " + strTableName + "(" + content + ")";
                SqlConnection conn = new SqlConnection(strDbIP);
                conn.Open();
                SqlCommand cmd = new SqlCommand(strSQL, conn);
                cmd.ExecuteNonQuery();
                conn.Close();
            }
        }</span>


2.4,具体应用

建表:

<span style="font-family:KaiTi_GB2312;font-size:18px;"> protected void btnCreateTable_Click(object sender, EventArgs e)
        {
            string strDefaultIP = TextBox1.Text;
            string strMyIP = TextBox2.Text;
            string strDatabaseName = "AngelTest";
            string strConnMine = "data source=" + "**********" + "; initial catalog=" + strDatabaseName + " ;" + "persist security info=True;user id=sa;password=*******"; 
            Dictionary<string, string> dic = new Dictionary<string, string>();
            dic.Add("sex ", " varchar(2)");
            dic.Add("name ", " varchar(8)");
            string strTableName = "TestTable";
            CreateTable(strDatabaseName,strConnMine,strTableName,dic);

        }</span>

建库:和建表差不多,就不展示了。


三、总结

如果说是用这种方式实现一个动态建库建表的话,这根本就不是什么新奇的东西。以前都学过这些,但是为什么自己一直还都不会熟练的应用,这是一个问题。接下来的博客,会介绍使用EF的codefirst方式,实现动态建库建表。

原文地址:https://www.cnblogs.com/hhx626/p/6010382.html