6

Sql ステートメントで .Net DateTime を使用することについていくつか質問がありますが、どれも私の問題を解決しませんでした。

次のコードを使用して、Oracle データベースにクエリを実行しています。

private DataTable QueryByIdAndDate(string id, DateTime fdate, DateTime tdate) {
    string query = "SELECT * FROM table WHERE ID = :id AND DATE_TIME BETWEEN :from AND :to"
    DbCommand cmd = db.CreateCommand();
    cmd.CommandType = CommandType.Text;
    cmd.CommandText = query;

    DbParameter fromDate = CreateDateParameter(cmd, fdate);
    fromDate.ParameterName = "from";
    DbParameter toDate = CreateDateParameter(cmd, tdate);
    toDate.ParameterName = "to"; 
    DbParameter idParam = CreateStringParameter(cmd, id);
    idParam.ParameterName = "id";

    cmd.Parameters.AddRange(new DbParameter[] { fromDate, toDate, idParam });
    return db.ExecuteQuery(cmd);
}

private DbParameter CreateDateParameter(DbCommand cmd, DateTime date) {
    DbParameter param = cmd.CreateParameter();
    param.DbType = DbType.DateTime;
    param.Direction = ParameterDirection.Input;
    param.Value = date;
    return param;
}

しかし、それは正しく動作しません。次のようにコードを試してみると:

DataTable result = QueryByIdAndDate("12345", DateTime.Now, DateTime.Now.AddDays(1));

次のエラーが表示されます。

DateTime のフォーマット方法に関係していると思いますが、これを信頼できる方法で修正する適切な方法がわかりません。

4

4 に答える 4

11

(コメントによると...)

この場合、パラメータの順序が重要であるように見えます...名前を付けているにもかかわらず。私はこれを予期していなかったでしょう、そしてそれはやや壊れたドライバーの兆候ですが、あなたのコードを次のように変更します:

cmd.Parameters.AddRange(new DbParameter[] { idParam, fromDate, toDate });

それを修正する必要があります。(ちなみに、これは必ずしもパラメーターを作成する方法ではありませんが、ここでは多少重要ではありません。)

日付/時刻の値を文字列として指定し始めないでください。必要以上の文字列変換を導入するのは本当に悪い考えです。

于 2012-04-24T20:18:18.427 に答える
3

DateTime値をフォーマットされた日付文字列に変換します。

private DbParameter CreateDateParameter(DbCommand cmd, DateTime date) 
{
     DbParameter param = cmd.CreateParameter();
     param.DbType = DbType.DateTime;
     param.Direction = ParameterDirection.Input;
     param.Value = date.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
     return param;
} 

文字列値を送信している場合でも、DbTypeはに設定されてDateTimeいるため、値は適切に変換されるはずです。

于 2012-04-24T20:11:18.883 に答える
2

Oracle は「DD-Mon-YYYY」としてフォーマットされた日付を想定しているため、基本的に日付値をそのようにフォーマットし、それをパラメーター値に割り当てる必要があります。

編集: ODP の最近のバージョンは、日時パラメーターをより適切に処理しているように見えることに気付きました。たとえば、日付/時刻列に対する WHERE 句に制約がある場合、これは問題なく機能します。

DateTime dt = new DateTime(2012, 5, 21);
cmd.Parameters.Add("some_date_param", dt);

ODP の最新バージョンでこの方法でクエリを実行すると、問題なく動作します。しかし、Oracleがそれらを受け入れるために、日付/時刻の値をフォーマットされた文字列として渡す必要があるコードがたくさんあります。

于 2012-04-24T20:15:02.810 に答える
2

それを見逃す可能性がある人については、@JonSkeet によって受け入れられた回答の下にある @kprobst によるコメント参照ください

BindByNameでプロパティを設定せずに名前バインディングを使用しようとしている場合は、パラメーター値などをどのようにフォーマットしてもかまいませんCommand

(Oracle プロバイダー API 全体は、ジャンク IMHO の山です)。

于 2016-11-22T14:58:19.423 に答える