应用程序运行时动态连接到服务器并创建数据库

时间:2017-06-24 08:00:41

标签: c# sql-server database dynamic

我希望我的应用程序连接到服务器并在其运行的任何PC上创建数据库。我有代码,但它只适用于我的计算机,而不适用于其他计算机,当我在其他计算机上运行它时,它将无法连接到该计算机服务器并且不会创建数据库

这是我的代码,我有启动画面形式,我希望,当应用程序运行时,检查该PC上是否存在数据库,以及是否不创建它。我的问题是,我的代码没有捕获服务器名称,只显示消息“服务器名称错误”

public partial class Splash : Form
    {
        public Splash()
        {
            InitializeComponent();              
            Properties.Settings.Default.Server = "(local)";
            timer.Enabled = true;
        }

        private void CheckDatabase()
        {
            try
            {
                using (SqlConnection conn = Helper.ConnectionToServer())
                {
                    if (Properties.Settings.Default.Server != string.Empty)
                    {
                        using (SqlCommand cmd = new SqlCommand(
                            "IF EXISTS (SELECT name FROM sys.databases WHERE name = 'MyDb') SELECT 1 ELSE SELECT 0",
                            conn))
                        {
                            conn.Open();
                            int value = (int)cmd.ExecuteScalar();
                            conn.Close();

                            if (value != 1)
                            {
                                MessageBox.Show("Database doesn't exist");
                                timer.Enabled = false;
                                CreateDatabase();

                            }

                        }
                    }
                    else
                    {
                        timer.Enabled = true;
                    }
                }
            }
            catch
            {
                MessageBox.Show("Bad server name");

            }
        }
        private void CreateDatabase()
        {
            string serverStr = "CREATE DATABASE [MyDb]";
            string databaseStr = @"
CREATE TABLE [dbo].[Worker] (
    [FirstName] NVARCHAR (50) NOT NULL,
    [Password] NVARCHAR (50) NOT NULL,
    [LastName] NVARCHAR (50) NOT NULL,

    PRIMARY KEY CLUSTERED ([Password] ASC)
);

CREATE TABLE [dbo].[Article] (
    [ItemName]     NVARCHAR (50) NOT NULL,
    [Barcode]  NVARCHAR (50) NOT NULL,
    [Price]   MONEY NOT NULL,

    CONSTRAINT [PK_Article] PRIMARY KEY CLUSTERED ([Barcode] ASC)
);";
            using (SqlConnection conn = Helper.ConnectionToServer())
            {
                try
                {
                    using (SqlCommand comm = new SqlCommand(serverStr, conn))
                    {
                        conn.Open();
                        comm.ExecuteNonQuery();
                        conn.Close();
                    }
                }
                catch
                {
                    MessageBox.Show("Bad server name");

                }

            }
            using (SqlConnection conn = Helper.ConnectionToDatabase())
            {
                using (SqlCommand comm = new SqlCommand(databaseStr, conn))
                {
                    conn.Open();
                    comm.ExecuteNonQuery();
                    conn.Close();
                    timer.Enabled = true;
                }
            }
        }

我还有一个帮助器类,每当我使用sql命令时都会使用它

 class Helper
    {
        public static SqlConnection ConnectionToDatabase()
        {
            string con = string.Format(@"Data Source=DESKTOP-RFJ38NM;Initial Catalog=MyDb;Integrated Security=True", Properties.Settings.Default.Server);
            return new SqlConnection(con);
        }
        public static SqlConnection ConnectionToServer()
        {
            string con = string.Format(@"Data Source=DESKTOP-RFJ38NM;Integrated Security=True", Properties.Settings.Default.Server);
            return new SqlConnection(con);
        }

    }

1 个答案:

答案 0 :(得分:1)

以下逻辑创建一个新数据库,即两个表。在前面我做了这个不是在初始形式,而是一个普通的形式,其中有一个部分我觉得应该是异步的,这是用于使用SmoApplication获取默认的SQL-Server实例名称,在那里你将添加对它的引用,在我的情况下这里有dll,你的计算机上有很多不同

C:\ Program Files \ Microsoft SQL Server \ 130 \ SDK \ Assemblies \ Microsoft.SqlServer.Smo.dll

在表单中有一个按钮和按钮的单击事件。单击时,代码将转移到一个单独的类,我将代码编组。

using System;
using System.Windows.Forms;

namespace StackOverFlow
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private async void button1_Click(object sender, EventArgs e)
        {
            var ops = await Operations.Create();

            if (ops.FoundServerInstanceName)
            {
                if (ops.CheckDatabase())
                {
                    MessageBox.Show("Ready to work with tables!!!");
                }
                else
                {
                    if (ops.HasException)
                    {
                        MessageBox.Show($"Encountered the following issue(s)\n{ops.ExceptionMessage}");
                    }
                    else
                    {
                        MessageBox.Show("Failed");
                    }
                }
            }
        }
    }
}

在Operations类的顶部(下面)有几个属性

  • 一个用于记住抛出的异常
  • 一个用于指示数据库是否存在的
  • 找到了指示SQL-Server的默认实例名称的属性。
  • 用于创建新数据库的连接字符串
  • 使用新数据库的连接字符串

方法Initialize获取SQL-Server的实例名称。然后检查数据库是否存在,然后我们是否创建数据库和表。

为了构建这个,我正在使用VS2015,我在消息中利用字符串插值并设置属性。

希望这对当前任务有用。

using Microsoft.SqlServer.Management.Smo;
using System;
using System.Data;
using System.Data.Sql;
using System.Data.SqlClient;
using System.Threading.Tasks;

namespace StackOverFlow
{

    public class Operations
    {
        string mExceptionMessage;
        public string ExceptionMessage { get { return mExceptionMessage; } }
        public bool HasException { get; set; }

        bool _databaseExists = false;

        bool mFoundServerInstanceName;
        public bool FoundServerInstanceName { get { return mFoundServerInstanceName; } }

        static string databaseServer;
        static string masterDefaultCatalog = "Master";
        string _masterConnectionString = $"Data Source={databaseServer};Initial Catalog={masterDefaultCatalog};Integrated Security=True";
        string MasterConnectionString
        {
            get
            {
                return _masterConnectionString;
            }
            set
            {
                _masterConnectionString = value;
            }
        }

        static string DefaultCatalog = "MyDb";
        string _ConnectionString = $"Data Source={databaseServer};Initial Catalog={DefaultCatalog};Integrated Security=True";
        string ConnectionString
        {
            get
            {
                return _ConnectionString;
            }
            set
            {
                _ConnectionString = value;
            }
        }
        public static async Task<Operations> Create()
        {
            var ops = new Operations();
            await ops.Initialize();
            return ops;
        }
        async Task<bool> Initialize()
        {
            return await GetDefaultInstanceAsync();
        }
        public async Task<bool> GetDefaultInstanceAsync()
        {
            var serverInstanceTable = new DataTable();
            try
            {
                await Task.Run(() => { serverInstanceTable = SmoApplication.EnumAvailableSqlServers(true); });
                if (serverInstanceTable != null)
                {
                    databaseServer = serverInstanceTable.Rows[0].Field<string>("name");
                    mFoundServerInstanceName = true;
                }
                else
                {
                    mFoundServerInstanceName = false;
                }

                return true;

            }
            catch (Exception ex)
            {
                mExceptionMessage = ex.Message;
                HasException = true;
                return false;
            }

        }
        /// <summary>
        /// Determine if the database exists
        /// </summary>
        /// <returns></returns>
        public bool CheckDatabase()
        {

            try
            {
                using (SqlConnection conn = new SqlConnection() { ConnectionString = MasterConnectionString })
                {
                    using (SqlCommand cmd = new SqlCommand($"IF EXISTS (SELECT name FROM sys.databases WHERE name = '{DefaultCatalog}') SELECT 1 ELSE SELECT 0", conn))
                    {
                        conn.Open();
                        int value = (int)cmd.ExecuteScalar();
                        conn.Close();

                        if (value != 1)
                        {
                            CreateDatabase();
                            _databaseExists = true;
                        }
                        else
                        {
                            _databaseExists = true;
                        }

                    }
                }
            }
            catch (Exception ex)
            {
                mExceptionMessage = ex.Message;
                _databaseExists = false;
                HasException = true;
            }

            return _databaseExists;

        }
        /// <summary>
        /// create the database and two tables
        /// </summary>
        /// <returns></returns>
        bool CreateDatabase()
        {
            string tableCreateScript = $@"
            USE [{DefaultCatalog}]
            CREATE TABLE [dbo].[Article](
                [ItemName] [nvarchar](50) NOT NULL,
                [Barcode] [nvarchar](50) NOT NULL,
                [Price] [money] NOT NULL,
             CONSTRAINT [PK_Article] PRIMARY KEY CLUSTERED 
            (
                [Barcode] ASC
            )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
            ) ON [PRIMARY];
            CREATE TABLE [dbo].[Worker](
                [FirstName] [nvarchar](50) NOT NULL,
                [Password] [nvarchar](50) NOT NULL,
                [LastName] [nvarchar](50) NOT NULL,
            PRIMARY KEY CLUSTERED 
            (
                [Password] ASC
            )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
            ) ON [PRIMARY];";

            using (SqlConnection conn = new SqlConnection() { ConnectionString = MasterConnectionString })
            {
                try
                {
                    using (SqlCommand comm = new SqlCommand($"CREATE DATABASE [{DefaultCatalog}];", conn))
                    {
                        conn.Open();

                        comm.ExecuteNonQuery();

                        comm.CommandText = tableCreateScript;
                        comm.ExecuteNonQuery();

                        return true;

                    }
                }
                catch (Exception ex)
                {
                    mExceptionMessage = ex.Message;
                    HasException = true;
                    return false;
                }

            }

        }
    }
}