1

このクエリ:

string.Format("SELECT COUNT(*) FROM {0}", tableName);

...「isValidTable(string tableName)」メソッドの根幹として使用しているこれは、tableName が存在しない場合 (具体的には、「指定されたテーブルが存在しません」)、例外をスローします。

その場合 (うまく動作しません。テーブル名を認識しないと手を投げます)、このコードは次のようになります。

public bool isValidTable(string tableName)
{
    bool validTable = false;
    string tblQuery = string.Format("SELECT COUNT(*) FROM {0}", tableName);
    try
    {
        SqlCeCommand cmd = new SqlCeCommand();
        cmd.CommandText = tblQuery;
        object objcnt = cmd.ExecuteScalar();
        if ((objcnt != null) && (objcnt != DBNull.Value)) 
        {
            validTable = Int32.Parse(objcnt.ToString()) > 0;
        } 
        else 
        {
            MessageBox.Show("NULL returned from isValidTable(). Remove this line."); //<- I never see this; if this is the case, an exception has been thrown
        }
    }
    catch 
    {
        return false;
    }
    return validTable;
}

...次のように簡略化できます/すべきです:

public bool isValidTable(string tableName)
{
    string tblQuery = string.Format("SELECT COUNT(*) FROM {0}", tableName);
    try
    {
        SqlCeCommand cmd = new SqlCeCommand();
        cmd.CommandText = tblQuery;
        cmd.ExecuteScalar();
    }
    catch 
    {
        return false;
    }
    return true;
}

?

アップデート

jp2code の意見: "select case when exists((select * from information_schema.tables where table_name = '{0}')) then 1 else 0 end"

列が存在するかどうかを確認するための同様のコードはありますか? 現在、私の isValidTable() と isValidColumn() クエリは似ています:

string tableQuery = string.Format("SELECT COUNT(*) FROM {0}", tableName);
string columnQuery = string.Format("SELECT COUNT({0}) FROM {1}", columnName, tableName);

...しかし、これを isValidTable() に使用できた場合:

string.Format("select case when exists((select * from information_schema.tables where table_name = '{0}')) then 1 else 0 end",
tableName);

...有効な列をチェックするために使用できる拡張機能もありますか? 何かのようなもの:

string.Format("select case when exists((select * from information_schema.tables where table_name = '{0}' and column_name = '{1}')) then 1 else 0 end",
tableName, columnName);

???

更新 2

提案されたSQLは「私のやり方」よりも「優れている」ことを認識していますが、何らかの理由で、「推奨される方法」を使用すると、必要なデータテーブルが存在すると認識されません(もちろん存在しますが) . 私が使用している古いバージョンのソフトウェアは、ネストされた選択/サブ選択を受け入れないか、または...???

いずれにせよ、コメントは物語を語っています:

string tblQuery = string.Format("SELECT COUNT(*) FROM {0}", tableName);
// This is doubtless "more better," but when I use it, I get "No current work; no inventory file"
//string tblQuery = string.Format("select case when exists((select * from information_schema.tables where table_name = '{0}')) then 1 else 0 end", tableName);
4

3 に答える 3

2

テーブルが見つからないことは、そのメソッドの通常の実行と見なされるため、例外の発生に依存しないでください。

あなたの例の標準外のものは、接続タイムアウトが発生することです。これは、メソッドの標準操作ではありません。

sys.tables代わりに、またはテーブルにクエリを実行してINFORMATION_SCHEMA.TABLES、テーブルが存在するかどうかを確認する必要があります。

于 2013-04-02T21:11:29.850 に答える
1

これを引き続き使用する場合は、少なくともSqlCeExceptionキャッチして無視する を指定してください。そうすれば、発生している可能性のある他のエラーを無意識のうちに無視することはありません。

テーブルが存在するかどうかの確認については、次の人気のある投稿を参照してください。

テーブルが SQL Server に存在するかどうかを確認する

実際、コードが機能する場合、例外はありません。したがって、デバッグとコードのリリース準備が整った後は、次のようになります。

public bool isValidTable(string tableName)
{
  bool validTable = false;
  string tblQuery =
    string.Format("select case when exists((select * from information_schema.tables where table_name = '{0}')) then 1 else 0 end",
    tableName);
  SqlCeCommand cmd = new SqlCeCommand();
  cmd.CommandText = tblQuery;
  try
  {
    cmd.Connection.Open();
    object objcnt = cmd.ExecuteScalar();
    if ((objcnt != null) && (objcnt != DBNull.Value)) 
    {
      validTable = Int32.Parse(objcnt.ToString()) > 0;
    } 
  }
  finally
  {
    cmd.Connection.Close();
  }
  return validTable;
}

その特定の SQL クエリは、この SO の質問からのソリューションを使用します。

SQL テーブルが存在するかどうかを確認する

更新:このDataReaderチェック ルーチンはどうですか:

public bool isValidTable(string tableName)
{
  bool validTable = false;
  string tblQuery =
    string.Format("select * from information_schema.tables where table_name='{0}'",
    tableName);
  SqlCeCommand cmd = new SqlCeCommand();
  cmd.CommandText = tblQuery;
  try
  {
    cmd.Connection.Open();
    // I don't know if this works because I don't have .NET 1.1
    SqlCeDataReader r = cmd.ExecuteReader();
    validTable = r.Read();
  }
  finally
  {
    cmd.Connection.Close();
  }
  return validTable;
}

DataReader 1.1 に関する MSDNのドキュメントには、(コメントで) SqlCeDataReader の既定の位置は最初のレコードの前です。データへのアクセスを開始するには、Read を呼び出す必要があります。したがって、Index = -1 から開始し、データへの最初のステップを行うには Read 呼び出しが必要です。

于 2013-04-03T13:34:54.827 に答える