如何在重新打开应用程序时创建新数据库?

时间:2013-09-16 20:33:01

标签: c# database logging

我有一个日志查看应用程序,它将日志语句写入数据库,然后将它们从数据库发送到日志查看器GUI。我希望能够打开多个日志查看器实例,但是当我这样做时,将创建一个与前一个查看器实例同名的数据库。我已经尝试创建一个具有不同名称的数据库(如果已经创建了一个但似乎不起作用)。有什么建议?这是创建/访问/销毁数据库的代码:

public class Database
{

    public bool hasAdminPriv
    {
        get;
        set;
    }

    public bool hasBeenCreated
    {
        get;
        set;
    }

    public Database()
    {
        hasAdminPriv = true;
        //Construction checks to see if user has Admin priveleges
        bool isElevated;
        WindowsIdentity identity = WindowsIdentity.GetCurrent();
        WindowsPrincipal principal = new WindowsPrincipal(identity);
        isElevated = principal.IsInRole(WindowsBuiltInRole.Administrator);
        if (!isElevated)
            hasAdminPriv = false;
    }

    //returns true if the database creation was successful
    public bool CreateDatabase()//creates a database dynamically by making a query request to the server
    {
        String str;
        SqlConnection myConn = new SqlConnection("Data Source=" + Environment.UserName + "-D1SD\\SQLEXPRESS; Initial Catalog=Master;Integrated Security=True");

        str = "CREATE DATABASE MyDatabase ON PRIMARY " +
        "(NAME = MyDatabase_Data, " +
        "FILENAME = 'C:\\Program Files (x86)\\Microsoft SQL Server\\MSSQL.1\\MSSQL\\Data\\MyDatabaseData.mdf', " +
        "SIZE = 30MB, MAXSIZE = 10GB, FILEGROWTH = 20%) " +
        "LOG ON (NAME = MyDatabase_Log, " +
        "FILENAME = 'C:\\Program Files (x86)\\Microsoft SQL Server\\MSSQL.1\\MSSQL\\Data\\MyDatabaseLog.ldf', " +
        "SIZE = 10MB, " +
        "MAXSIZE = 1GB, " +
        "FILEGROWTH = 10%)";

        SqlCommand myCommand = new SqlCommand(str, myConn);
        try
        {
            myConn.Open();
            myCommand.ExecuteNonQuery();
        }
        catch (System.Exception ex)
        {
            int done = 0;
            while (done < 10)
            {
                String str2 = "CREATE DATABASE" + done + " MyDatabase ON PRIMARY " +
                                "(NAME = MyDatabase_Data, " +
                                "FILENAME = 'C:\\Program Files (x86)\\Microsoft SQL Server\\MSSQL.1\\MSSQL\\Data\\MyDatabaseData.mdf', " +
                                "SIZE = 30MB, MAXSIZE = 10GB, FILEGROWTH = 20%) " +
                                "LOG ON (NAME = MyDatabase_Log, " +
                                "FILENAME = 'C:\\Program Files (x86)\\Microsoft SQL Server\\MSSQL.1\\MSSQL\\Data\\MyDatabaseLog.ldf', " +
                                "SIZE = 10MB, " +
                                "MAXSIZE = 1GB, " +
                                "FILEGROWTH = 10%)";
                SqlCommand myCommand2 = new SqlCommand(str2, myConn);
                try{
                    myCommand2.ExecuteNonQuery();
                }
                catch{
                    ++done; 
                }
                myConn.Close();
                hasBeenCreated = true;
                return true;
            }

            return false;
        }
        finally
        {
            if (myConn.State == ConnectionState.Open)
            {
                myConn.Close();
            }
        }
        hasBeenCreated = true;
        return true;
    }

    //Creates the table in the database by a query request
    //a return value of true means Database was created succesfully
    public bool CreateTable()
    {
        SqlConnection myConn = new SqlConnection("Data Source=" + Environment.UserName + "-D1SD\\SQLEXPRESS; Initial Catalog=MyDatabase;Integrated Security=True");
        string createString = "CREATE TABLE storage (ID INT NOT NULL, Level varchar(255) , LevelInt INT, DateTime varchar(255),Counter smallint,Device varchar(255), Source varchar(255), Description varchar(255),PRIMARY KEY (ID))"; //YOUR SQL COMMAND TO CREATE A TABLE
        SqlCommand create = new SqlCommand(createString, myConn);
        myConn.Open();
        create.ExecuteNonQuery();
        myConn.Close();
        return true;
    }

    //Add the element's values to the database/table to later recall/reorder
    public bool addElement(LogParse log,int num)
    {
        SqlConnection con = new SqlConnection("Data Source=" + Environment.UserName + "-D1SD\\SQLEXPRESS;Initial Catalog=MyDatabase;Integrated Security=True");
        try
        {
            con.Open();
            SqlCommand cmd = new SqlCommand("Insert into storage(ID, Level, LevelInt, DateTime, Counter, Device, Source, Description) values(" + num + ",@Level, @LevelInt, @DataTimeItem,@counterItem,@deviceItem,@sourceItem,@descItem)", con);
            cmd.Parameters.AddWithValue("@Level", log.Level);
            cmd.Parameters.AddWithValue("@LevelInt", log.LevelInt);
            cmd.Parameters.AddWithValue("@DataTimeItem", log.TimeStamp);
            cmd.Parameters.AddWithValue("@counterItem", log.SequentialNumber);
            cmd.Parameters.AddWithValue("@deviceItem", log.Device);
            cmd.Parameters.AddWithValue("@sourceItem", log.Source);
            cmd.Parameters.AddWithValue("@descItem", log.Description);
            cmd.ExecuteNonQuery();
            con.Close();

        }
        catch (Exception ee)
        {
            return false;
        }
        return true;
    }

    //outputs a string array with all the values in the database
    public LogParse[] readValue(int start, int end)
    {
        SqlConnection con = new SqlConnection("Data Source=" + Environment.UserName + "-D1SD\\SQLEXPRESS;Initial Catalog=MyDatabase;Integrated Security=True");
        con.Open();
        LogParse[] s = new LogParse[end - start];
        try
        {
            using (var oCommand = new SqlCommand("SELECT * From storage WHERE ID BETWEEN @Start AND @End", con))
            {
                oCommand.Parameters.AddWithValue("@Start", start);
                oCommand.Parameters.AddWithValue("@End", end);
                using (var oReader = oCommand.ExecuteReader())
                {
                    int i = 0;
                    while (oReader.Read() && i < end-start)
                    {
                        //s[i] = oReader.GetString(1) + oReader.GetString(2) + oReader.GetString(3);
                        String Level = oReader.GetString(1);
                        Int32 LevelInt = oReader.GetInt32(2);
                        String Datetime = oReader.GetString(3);
                        Int16 SequentialNumber = (Int16)oReader.GetValue(4);
                        String Device = oReader.GetString(5);
                        String Source = oReader.GetString(6);
                        String Description = oReader.GetString(7);

                        s[i] = new LogParse();
                        s[i].Level = Level;
                        s[i].LevelInt = LevelInt;
                        s[i].TimeStamp = DateTime.Parse(Datetime);
                        s[i].SequentialNumber = SequentialNumber;
                        s[i].Device = Device;
                        s[i].Description = Description;
                        s[i].Source = Source;
                        ++i;
                    }
                }
            }
        }
        catch
        {

        }
        con.Close();
        return s;
    }

    //Deletes the database by a query statement
    //a return value of true means the delete was succesful
    public static bool deleteDatabase()
    {
        String str;
        SqlConnection myConn = new SqlConnection("Data Source=" + Environment.UserName + "-D1SD\\SQLEXPRESS; Initial Catalog=Master;Integrated Security=True");
        str = @"ALTER DATABASE MyDatabase SET SINGLE_USER WITH ROLLBACK IMMEDIATE;DROP DATABASE [MyDatabase]";
        SqlCommand myCommand = new SqlCommand(str, myConn);
        try
        {
            myConn.Open();
            myCommand.ExecuteNonQuery();
        }
        catch (System.Exception ex)
        {
            return false;
        }
        finally
        {
            if (myConn.State == ConnectionState.Open)
            {
                myConn.Close();
            }
        }
        return true;
    }
}

2 个答案:

答案 0 :(得分:3)

不要创建另一个数据库或表,这是邪恶的。只需将实例ID添加到表storage中即可。在编写新日志时只需添加实例ID,从DB读取时也一样,将实例ID放入where子句。

另一个问题是选择好的实例ID,您的场景对我来说不是很清楚,但如果您希望每个新的应用程序实例都有单独的数据,只需创建新的GUID并将其用作实例ID。

例如,您可以在Database类中拥有静态属性InstanceID,您的类可能如下所示:

public class Database
{
    public static Guid InstanceID = new Guid();

    //Add the element's values to the database/table to later recall/reorder
    public bool addElement(LogParse log,int num)
    {
        SqlConnection con = new SqlConnection("Data Source=" + Environment.UserName + "-D1SD\\SQLEXPRESS;Initial Catalog=MyDatabase;Integrated Security=True");
        try
        {
            con.Open();
            SqlCommand cmd = new SqlCommand("Insert into storage(ID, InstanceID, Level, LevelInt, DateTime, Counter, Device, Source, Description) values(" + num + ",@Level, @LevelInt, @DataTimeItem,@counterItem,@deviceItem,@sourceItem,@descItem)", con);
            // writing InstanceID
            cmd.Parameters.AddWithValue("@InstanceID", Database.InstanceID);
            cmd.Parameters.AddWithValue("@Level", log.Level);
            cmd.Parameters.AddWithValue("@LevelInt", log.LevelInt);
            cmd.Parameters.AddWithValue("@DataTimeItem", log.TimeStamp);
            cmd.Parameters.AddWithValue("@counterItem", log.SequentialNumber);
            cmd.Parameters.AddWithValue("@deviceItem", log.Device);
            cmd.Parameters.AddWithValue("@sourceItem", log.Source);
            cmd.Parameters.AddWithValue("@descItem", log.Description);
            cmd.ExecuteNonQuery();
            con.Close();

        }
        catch (Exception ee)
        {
            return false;
        }
        return true;
    }

    //outputs a string array with all the values in the database
    public LogParse[] readValue(int start, int end)
    {
        SqlConnection con = new SqlConnection("Data Source=" + Environment.UserName + "-D1SD\\SQLEXPRESS;Initial Catalog=MyDatabase;Integrated Security=True");
        con.Open();
        LogParse[] s = new LogParse[end - start];
        try
        {
            // select with InstanceID
            using (var oCommand = new SqlCommand("SELECT * From storage WHERE InstanceID = @InsID ID BETWEEN @Start AND @End", con))
            {
                oCommand.Parameters.AddWithValue("@Start", start);
                oCommand.Parameters.AddWithValue("@End", end);
                oCommand.Parameters.AddWithValue("@InsID", Database.InstanceID);
                using (var oReader = oCommand.ExecuteReader())
                {
                    int i = 0;
                    while (oReader.Read() && i < end-start)
                    {
                        //s[i] = oReader.GetString(1) + oReader.GetString(2) + oReader.GetString(3);
                        String Level = oReader.GetString(1);
                        Int32 LevelInt = oReader.GetInt32(2);
                        String Datetime = oReader.GetString(3);
                        Int16 SequentialNumber = (Int16)oReader.GetValue(4);
                        String Device = oReader.GetString(5);
                        String Source = oReader.GetString(6);
                        String Description = oReader.GetString(7);

                        s[i] = new LogParse();
                        s[i].Level = Level;
                        s[i].LevelInt = LevelInt;
                        s[i].TimeStamp = DateTime.Parse(Datetime);
                        s[i].SequentialNumber = SequentialNumber;
                        s[i].Device = Device;
                        s[i].Description = Description;
                        s[i].Source = Source;
                        ++i;
                    }
                }
            }
        }
        catch
        {

        }
        con.Close();
        return s;
    }
}

顺便说一句。 不要吞下异常!我保持你的代码相同,但请不要这样做,它也是邪恶的,另一件事是如果你的addElement方法中有一个例外,你的连接将不会被关闭,请使用Using statement

答案 1 :(得分:0)

根本听起来不安全,也许一个数据库有几个用户表来存储每个用户的日志文件,但这对我来说听起来不对。

否则是在创建应用程序时启动应用程序时随机分配的变量,而不是数据库名称。

但是如果你做错了,那里会有很多数据库,但看起来你已经找到了尺寸和其他一些东西来防止它们超过服务器机器。

评论中的其他信息

如果要在数据库上使用表(我认为这是你真正需要的),那么单独创建数据库,然后在每次打开时在应用程序中创建随机命名的表,你可能想要另一个表这将跟踪表格及其打开的时间,甚至可能是用户打开它们以及类似的东西