3

Windows のスケジュールされたタスクとして実行される C# プログラムがあります。このプログラムは、読み込み、SQL クエリを実行し、データセットに保存された結果を電子メールで送信してから閉じます。昨日の日付を使用する以外はすべてあります。

ここに私の現在のクエリがあります:

SELECT        Store_Id, Paid_Out_Amount, Paid_Out_Comment, Paid_Out_Datetime, Update_UserName, Till_Number, @startdate AS Start, @enddate AS Today
FROM            Paid_Out_Tb
WHERE        (Store_Id = 1929) AND (Paid_Out_Datetime BETWEEN @startdate AND @enddate)

明らかに、クエリ時に @startdate と @enddate を割り当てる必要があります。午前 12 時から午後 11 時 59 分までが必要なので、これが開始と終了の理由です。たとえば。今日プログラムを実行したい場合、昨日 (23 日) が検索されるため、@startdate には 7/22/12 00:00:00 が割り当てられ、@enddate には 7/22/12 23:59:59 が割り当てられます。 .

プログラムの代わりにクエリでそれを行う方が理にかなっていますか? もしそうなら、どうすればクエリを変更できますか?

4

8 に答える 8

5

コンストラクターを呼び出さずに常に昨日の始まりを得るために、既存の回答をわずかに改善しました。DateTime

var todayStart = DateTime.Today;
var yesterdayStart = todayStart.AddDays(-1);
var yesterdayEnd = todayStart.AddSeconds(-1); // Ick...

これは、「今日」の意味に現在のシステム タイム ゾーンを使用することに注意してください。それでよろしいですか? 以下の使用を検討してください。

var todayUtcStart = DateTime.UtcNow.Date;
...

BETWEENエンドポイントを包括的として扱うのは残念です-もしそれが

start <= value && value < end

次に、2 つの真夜中の値を指定するだけで、より明確になります。

また、データベースとのやり取りがよりクリーンになるわけではありませんが、日付と時刻の他の用途については、特に日付を表​​すためのデータ型を含む私のNoda Timeライブラリを検討することをお勧めします(および「時間」日付と時刻を使用してコードを明確にすることが目的です。そうじゃなかったら失敗です!

于 2012-07-23T16:54:05.220 に答える
4

C# で昨日の始まりを計算できます。

var yesterday = DateTime.Now.AddDays(-1);
var startOfYesterday = new DateTime(yesterday.Year, yesterday.Day, yesterday.Month);
com.Parameters.AddWithValue("@enddate", startOfYesterday);

SQL Server 2008 以降を使用している場合は、データ型を からdatetimeに変更できますdate。後者は日付のみを保存できるため、日時の部分について心配する必要はありません。

于 2012-07-23T16:52:09.780 に答える
2

between日付間隔を扱う場合は使用しないでください。>=とを使用する方がはるかに簡単で安全<です。

このようなものは、パラメーターなしで昨日のものを提供します。

SELECT Store_Id, Paid_Out_Amount, Paid_Out_Comment, Paid_Out_Datetime, Update_UserName, Till_Number, @startdate AS Start, @enddate AS Today
FROM   Paid_Out_Tb
WHERE  Store_Id = 1929 AND 
       Paid_Out_Datetime >= dateadd(day, datediff(day, 0, getdate())-1, 0) and
       Paid_Out_Datetime < dateadd(day, datediff(day, 0, getdate()), 0)
于 2012-07-23T17:03:06.623 に答える
0

SQL でもこれを行うことができます。

SELECT Store_Id, Paid_Out_Amount, Paid_Out_Comment, 
        Paid_Out_Datetime, Update_UserName, Till_Number, @startdate AS Start, @enddate AS Today
FROM            Paid_Out_Tb
WHERE        (Store_Id = 1929) 
AND (Paid_Out_Datetime BETWEEN DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE())) 
    AND dateadd(second, -1, DATEADD(dd, 1, DATEDIFF(dd, 0, GETDATE()))))
于 2012-07-23T17:04:04.923 に答える
0

クエリ自体に入れたい場合:

select (date_trunc('day', NOW()) - INTERVAL '1 day'); -- Yesterday Start
select (date_trunc('day', NOW()) - INTERVAL '1 second'); -- Yesterday End
于 2012-07-23T17:08:42.230 に答える
0

これも機能する可能性がありますが、パフォーマンス上の欠点があります。

 DateTime yesterday = DateTime.Today;
 Thread.Sleep(1000 * 60 * 60 * 24);
于 2012-07-23T17:01:00.807 に答える
0

常にパラメーター化されたクエリを使用する必要があります。

探しているものをサポートするために、昨日の日付を変数にドロップし、その変数をパラメーターに渡すことができます。

于 2012-07-23T16:53:55.793 に答える
0

私はあなたがすべてこの方法で何かを探していると思います

DateTime yesterdDaysDateTime = DateTime.Now.AddDays(-1);
于 2012-07-23T16:51:59.187 に答える