0

ログ ステートメントをデータベースに書き込み、データベースからログ ビューア 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;
    }
}
4

2 に答える 2

3

別のデータベースやテーブルを作成しないでください。悪です。インスタンス ID を table に追加するだけstorageです。また、新しいログを書き込むときはインスタンス ID を追加するだけです。DB から読み取るときも同様で、インスタンス ID を where 句に入れます。

もう 1 つの問題は、適切なインスタンス 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 を使用してください。

于 2013-09-16T22:32:45.567 に答える
0

これはまったく安全とは言えません。おそらく、1 つのデータベースに複数のユーザー テーブルがあり、各ユーザーのログ ファイルが格納されているのですが、これは私には正しくないように思えます。

それ以外の場合は、データベース作成時のデータベース名の代わりに、アプリケーションの開始時にランダムに割り当てられる変数です。

しかし、何か間違ったことをすると、そこには多くのデータベースが存在することになりますが、サーバー マシンを圧倒しないようにサイジングやその他のことを考え出したようです。

コメントからの追加情報

データベースでテーブルを使用する場合(これが本当に必要だと思います)、データベースを個別に作成し、アプリケーションを開くたびにランダムな名前のテーブルをアプリケーション内に作成する場合は、保持する別のテーブルが必要になる場合がありますテーブルとそれらが開かれた時間の追跡、おそらくどのユーザーがテーブルを開いたのかなど

于 2013-09-16T20:44:19.293 に答える