5
sqlQuery = "SELECT [ID] from [users] WHERE CallerName=@CallerName";

OleDbConnection conn = new OleDbConnection(connectionString);
conn.Open();
cmd = new OleDbCommand(sqlQuery, conn);
cmd.CommandText = sqlQuery;
cmd.Parameters.Add("@CallerName", OleDbType.VarChar).Value = labelProblemDate.Text.Trim();
cmd.Parameters["@CallerName"].Value = name;
cmd.ExecuteNonQuery();          
conn.Close();

これは、パラメーターを使用して SELECT クエリからデータを読み取る方法であると言われましたが、機能していません。私は何か間違ったことをしたと思います。

WinForms と Microsoft Access 2007 を使用しています

4

4 に答える 4

7

あなたの答えがあるように見えますが、あなたのサンプルコードからいくつかのことを指摘したかったのです:

sqlQuery = "SELECT [ID] from [users] WHERE CallerName=@CallerName";

OleDbConnection conn = new OleDbConnection(connectionString);
conn.Open();
cmd = new OleDbCommand(sqlQuery, conn);
cmd.CommandText = sqlQuery;
cmd.Parameters.Add("@CallerName", OleDbType.VarChar).Value = labelProblemDate.Text.Trim();
cmd.Parameters["@CallerName"].Value = name;
cmd.ExecuteNonQuery();
conn.Close();

最初に、SQL クエリが Microsoft SQL 構文を使用しており、Microsoft Access はわずかに異なる構文を好むことに注意してください。列名を角かっこで囲む代わりに、チルダ マークを使用します。

sqlQuery = "SELECT `ID` from `users` WHERE `CallerName`=@CallerName";

次に、SQL クエリで、Microsoft Access は名前付きパラメーターを受け入れないことに注意してください。上記の SQL テキスト@CallerNameは問題なく実行されますが、OleDb オブジェクトからは次のように表示されます。

sqlQuery = "SELECT `ID` from `users` WHERE `CallerName`=?";

後で、テキスト SQL の代わりにストアド プロシージャを使用することにした場合は、パラメーターを追加した後、コマンドを実行する前に、必ずPrepare()を呼び出してください。OleDbCommand

複数のパラメーターがある場合は、これらのパラメーターをOleDbCommandSQL テキストで呼び出したのと同じ順序で に追加してください。OleDb は名前を気にしませんが、それらを自分で使用して支援することができます。クエリでは使用されません。@CallerNameは、SQL テキスト内の何かと一致しようとはしません。

次に、OleDbParameterアイテムの使用状況を確認したいと思います。OleDbCommand以下の 2 行では、値labelProblemDate.Text.Trim()を使用してパラメーターを 1 つ追加しています。次の行では、同じパラメーターの値を変数に再割り当てしています (これは不明です)。 ) と呼ばれnameます。パラメータを 1 つの値で宣言してから、別の値に再割り当てするのはよくありません。

以下の変更されたスニペットを使用して、同じ結果を得ることができます (以下に示すように、データベースで指定されているサイズ フィールドを追加することを忘れないでください)。

cmd.Parameters.Add("@CallerName", OleDbType.VarChar, 255).Value = labelProblemDate.Text.Trim();
// cmd.Parameters["@CallerName"].Value = name;

同様に、 yourはパラメーターを使用OleDbCommandして作成されているため、コマンドのプロパティを指定する必要はありません。sqlQueryCommandText

cmd = new OleDbCommand(sqlQuery, conn);
//cmd.CommandText = sqlQuery;

最後に、他の人が言ったように、SQL ステートメントが示唆するようにデータをクエリする場合は、呼び出すのではなく、データを読み込む必要があります( Non QueryExecuteNonQuery()と呼ばれることに注意してください)。

要約すると、ここに書きました:

sqlQuery = "SELECT `ID` from `users` WHERE `CallerName`=?";
int result = 0;
OleDbConnection conn = new OleDbConnection(connectionString);
try {
  conn.Open();
  var cmd = new OleDbCommand(sqlQuery, conn);
  //cmd.CommandText = sqlQuery; This command was specified by your initializer
  cmd.Parameters.Add("?", OleDbType.VarChar, 255).Value = labelProblemDate.Text.Trim();
  //cmd.Parameters["@CallerName"].Value = name; Possible bug here
  using (OleDbDataReader reader = cmd.ExecuteReader())
  {
    if(reader.HasRows)
    {
      reader.Read();
      result = reader.GetInt32(0);
    }
  }
} finally {
  conn.Close();
}
return result;

finallyプログラムが何らかの理由でエラーをスローする場合に備えて、必ず Close をブロックに入れます。これにより、アプリケーションがクラッシュしてファイルが開いたままになるのを防ぐことができます。私が見つけたusing句は、接続が完了したときに必ずしも接続を閉じるとは限りません(そうする必要があるように)。

これが役立つことを願っています。現時点での知識を更新OleDbしていて、いくつかのことを指摘したいと思いました。

于 2012-05-16T15:27:34.270 に答える
6

ExecuteNonQuery はデータを返さず、コマンドの影響を受ける行のみを返し
ます

OleDbDataReader reader = cmd.ExecuteReader();           
if(reader.HasRows)
{
    reader.Read();
    var result = reader.GetInt32(0);
}
于 2012-04-27T16:37:40.063 に答える
2

クエリが 1 つの値を返す場合、 を使用ExecuteScalarして値を取得できます。 ExecuteNonQueryデータベースから値を返しません。むしろ、ステートメントなどで使用することを目的としてUPDATEおり、ステートメントによって影響を受ける行の数を返します。

ご存知かもしれませんが、一般に、SELECT クエリは複数の行 (および複数の列) を返すことができるため、「SELECT クエリからデータを読み取る」にはExecuteReaderDbDataReader.

于 2012-04-27T16:36:51.923 に答える
1

データを読み取って DataTable にロードするには:

OleDataReader rdr = (OleDataReader) cmd.ExecuteReader();
DataTable dt = new DataTable();
dt.Load(rdr);

スカラー値データを読み取って変数にロードするには:

int result = (int)cmd.ExecuteScalar(); //Assume scalar value to be return is int

役立つことを願っています

于 2012-04-27T16:48:14.053 に答える