2017-03-17 25 views
0

テーブルが存在するかどうかを確認するメソッドを作成しようとしています。私はデータベースを介して一貫性を維持するためにusingステートメントを使用しようとしています。コマンドが存在するかどうかを確認する

public void checkTableExists() 
{ 
    connectionString = @"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\keith_000\Documents\ZuriRubberDressDB.mdf;Integrated Security=True;Connect Timeout=30"; 

    string tblnm = "BasicHours"; 
    string str = "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = " + tblnm + ");"; 

    SqlDataReader myReader = null; 
    int count = 0; 

    try 
    { 
     using (SqlConnection connection = new SqlConnection(connectionString)) 
     { 
      using (SqlCommand command = new SqlCommand(str, connection)) 
      { 
       connection.Open(); 

       using (SqlDataReader reader = command.ExecuteReader()) 
       { 
        MessageBox.Show("The count is " + count); 

        myReader = command.ExecuteReader(); 

        while (myReader.Read()) 
        { 
         count++; 
        } 

        myReader.Close(); 

        MessageBox.Show("Table Exists!"); 
        MessageBox.Show("The count is " + count); 
       } 

       connection.Close(); 
      } 
     } 
    } 
    catch (SqlException ex) 
    { 
     MessageBox.Show("Sql issue"); 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show("Major issue"); 
    } 

    if (count > 0) 
    { 
     MessageBox.Show("Table exists"); 
    } 
    else 
    { 
     MessageBox.Show("Table doesn't exists"); 
    } 
} 

tryブロックにヒットしたときに例外をスローします。それはSqlExceptionブロックをキャッチします。

これは私がデータベースと再びやりとりすることを学んでいるところです。その解決方法は良いでしょうが、もっと重要なのは、コードを改善する方法をどこで知る必要があるのか​​を簡単に説明します。

おかげ

キース

+2

TABLE_NAMEは文字列フィールドです。変数を一重引用符で囲む必要がありますが、パラメータをよく使用してください。 – Steve

+1

そのようなSQLクエリを連結しないでください。 (tblnm = "BasicHours; TRUNCATE TABLE [BasicHours];"代わりにParameterized SqlCommandオブジェクトを使用してください。 – WraithNath

+2

あなたはどんな例外を取得していますか? –

答えて

7

文字列の値を検索するクエリを直接記述すると、この値は 'BasicHours'のように一重引用符で囲む必要があるため、コードが失敗します。

実際のコードにはいくつか改善が加えられていますが、
まず、単純化されたSQLコマンドを使用できます。
第2に、文字列連結の代わりにパラメータを使用します。クエリは1「列」で1行のみを返し、この単一のセルの値が1つのまたは0
はるかに少ないオーバーヘッドのいずれかであるため、

SqlCommand cmd = new SqlCommand(@"IF EXISTS(
    SELECT 1 FROM INFORMATION_SCHEMA.TABLES 
    WHERE TABLE_NAME = @table) 
    SELECT 1 ELSE SELECT 0", connection); 

cmd.Parameters.Add("@table", SqlDbType.NVarChar).Value = tblName; 
int exists = (int)cmd.ExecuteScalar(); 
if(exists == 1) 
    // Table exists 

このコマンドテキストは、SqlDataReaderのを使用する必要はありません。 。

これからの部分は、文字列を連結するSQLクエリを作成しないことが最も重要です。この方法は問題を引き起こすことがよく知られています。 悪化すると、SQL Injectionと呼ばれ、データベースを破壊したり、機密情報をハッカーに明らかにする可能性があります。連結された文字列に単一引用符が含まれている場合、マイナーなものはクラッシュします。常にパラメータ化されたクエリを使用します。

1

私は私のプロジェクトで、次のコードを使用して私のために働いています:string tblnm = "BasicHours";

try 
{ 
    using (con = new SqlConnection(Constr);) 
     { 
      con.Open(); 
      string query = $"IF EXISTS (SELECT * FROM sys.tables WHERE name = '{tableName}') SELECT 1 ELSE Select 0;" 
      Exists = int.Parse(sqlQuery.ExecuteScalar().ToString())==1; 
      con.Close(); 
     } 

    } 
    catch{} 
0

問題はラインである可能性があります。テーブル名は文字列であり、アポストロフィである必要があります。string tblnm = "'BasicHours'";

例外のメッセージと詳細を記録することもできます。

0

この問題のお手伝いをありがとうございます。これは私が実装している解決策です。

public void checkTableExists() 
    { 
     connectionString = @" 
     Data Source=(LocalDB)\MSSQLLocalDB; 
     AttachDbFilename=C:\Users\keith_000\Documents\ZuriRubberDressDB.mdf; 
     Integrated Security=True; 
     Connect Timeout=30"; 

     string tblName = @"BasicHours"; 
     string str = @"IF EXISTS(
       SELECT 1 FROM INFORMATION_SCHEMA.TABLES 
       WHERE TABLE_NAME = @table) 
       SELECT 1 ELSE SELECT 0"; 

     try 
     { 
      using (SqlConnection connection = new SqlConnection(connectionString)) 
      { 
       using (SqlCommand command = new SqlCommand(str, connection)) 
       { 
        connection.Open(); 
        SqlCommand cmd = new SqlCommand(str, connection); 

        cmd.Parameters.Add("@table", SqlDbType.NVarChar).Value = tblName; 
        int exists = (int)cmd.ExecuteScalar(); 
        if (exists == 1) 
        { 
         MessageBox.Show("Table exists"); 
        } 
        else 
        { 
         MessageBox.Show("Table doesn't exists"); 
        } 
        connection.Close(); 
       } 
      } 
     } 
     catch (SqlException ex) 
     { 
      MessageBox.Show("Sql issue"); 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show("Major issue"); 
     } 
    } 
関連する問題