2010-11-24 10 views
0

誕生日の列を持つすべてのユーザーを保持する才能テーブルがあります。指定された年齢層の中で才能が最も良い方法は何でしょうか。ここに私が持っているものがありますが、カップルの日でオフになっているようです。そこには良い方法がありますか?c#、年齢範囲を指定してユーザーを選択するSQLを構築

// BUILD SQL FROM FORM DATA 
sqlString += "SELECT * from Talent"; 

if (minAge != 0 || maxAge != 120) 
{ 
    // The age criteria has been change, filter by age. 

    // select all talents that have birthdays between the following 2 dates. 
    DateTime startDate = (DateTime.Now - new TimeSpan((maxAge * 365), 0, 0, 0)); // maxAge * 365 = totalDays 
    DateTime endDate = (DateTime.Now - new TimeSpan((minAge * 365), 0, 0, 0)); 
    sqlString += " WHERE Birthdate BETWEEN '" + startDate.ToString() + "' AND '" + endDate.ToString() + "'"; 
} 
+0

オフトピックですが、パラメータ化されたSQL *を使用しない*文字列連結を使用してクエリを作成してください。 (この特別なケースでは、SQLインジェクションのリスクはないが、とにかくパラメータ化されたSQLはより洗練されている) – LukeH

+0

あなたの '(minAge!= 0 || maxAge!= 120)'節は奇妙です: -1000〜120は大丈夫です。 0〜999は大丈夫です。 120〜0はokなど。 – LukeH

+0

@ルークH。いくつかのサンプルコードを提供できますか?私はデータベースの年齢がintではないことに注意してください...私は誕生日のdateTimeしか持っていません。年齢計算にこれを使用します。 – RayLoveless

答えて

0

個人的に、私は、終了日の範囲で000点に注意してください(startDate.ToString("yy-MM-dd 00:00:00.000")endDate.ToString("yy-MM-dd 23:59:59.000")作品のベストを使用して発見しました。何らかの理由で、私の経験では、SQLはおそらく丸め誤差のいくつかの種類に(オフになっていますそれは範囲である。余談として

に来るとき)、あなたは時間の計算のためにTimeSpanオブジェクトから静的メソッドを使用することができます。例えばTimeSpan.FromDays(...)

0

問題は日付だけでなく、時間を考慮した、DateTime.Nowに関連するかもしれません。 DateTime.Todayと交換してください。

0

なぜDateTime.AddYearsメソッドを使用しないでください。

DateTime startDate = (DateTime.Now - new TimeSpan((maxAge * 365), 0, 0, 0)); 

のinsated

DateTime startDate = DateTime.Now.AddYears(-maxAge); 

もう一つは、次のとおりです。代わりにStringBuilderを使用して、SQLクエリを構築するために文字列の間+演算子を使用しないでください。 SQL Serverを使用していると仮定すると、

+0

'StringBuilder'は、SQLを構築するための単純な文字列連結よりもわずかに悪くありません。パラメータ化されたSQLコマンドを使用し、文字列の操作を完全に避ける必要があります。 @ LukeK。 – LukeH

+0

申し訳ありませんが、文字列連結またはstringBuilderが必要です。ユーザーが指定した年齢の範囲を指定していない場合(つまり、値が0と120の場合)、WHERE句はまったく必要ありません。 aの各レコードを検証する必要はありません。 – RayLoveless

+0

@レイ:LukeHは正しいです。私が 'StringBuilder'を提案した理由は、ここでもう少し詳細な提案はできません。私は将来、より多くのORMを見ることができると考えています。SQL文に問い合わせるよりもはるかに優れたソリューションがあります。 –

1

...

using (var connection = new SqlConnection(connString)) 
    using (var command = connection.CreateCommand()) { 

     string tsql = @" 
      select * 
       from Talent 
       where DATEDIFF(YEAR, BirthDay, GETDATE()) BETWEEN @minAge AND @maxAge"; 

     command.CommandText = tsql; 
     command.CommandType = CommandType.Text; 

     int minAge = 1; 
     int maxAge = 120; 

     SqlParameter minAgeParam = command.CreateParameter(); 
     minAgeParam.Direction = ParameterDirection.Input; 
     minAgeParam.DbType = SqlDbType.TinyInt; 
     minAgeParam.ParameterName = "@minAge"; 
     minAgeParam.Value = minAge; 

     SqlParameter maxAgeParam = command.CreateParameter(); 
     maxAgeParam.Direction = ParameterDirection.Input; 
     maxAgeParam.DbType = SqlDbType.TinyInt; 
     maxAgeParam.ParameterName = "@maxAge"; 
     maxAgeParam.Value = maxAge; 

     // Just unsure here whether I must add the parameters to the command, 
     // or if they are already part of it since I used the 
     // SqlCommand.CreateParameter() method. 
     // Been too long since I haven't done any ADO.NET 
     command.Parameters.Add(minAgeParam); 
     command.Parameters.Add(maxAgeParam); 

     connection.Open(); 

     SqlDataReader reader = null; 

     try { 
      reader = command.ExecuteReader(); 
      // Process your records here... 
     } finally { 
      connection.Close() 
      command.Dispose(); 
      connection.Dispose(); 
      if (reader != null) { 
       reader.Dispose(); 
      } 
     } 
    } 

@minAge@maxAgeはあなたの年齢パラメータです。

また、DATEDIFF TSQL functionに日、月、時間、分、秒などの違いを考慮するように指示することもできます。したがって、それに応じてパラメータ値を変換する必要があります。

+0

これは、実際の誕生日、生年のみを考慮に入れません。 – LukeH

+0

@ LukeH:OPは、0歳<120歳のすべてのタレントを尋ねましたが、彼は実際に言及した答えでそうすることができます。それにもかかわらず、OPは、年、月、日、時、分、秒のいずれかの日付範囲を区別することができます。すべては、DATEDIFF関数に何を区別するかを伝えることです。 –

+1

こんにちは、私はDATEDIFFが私のために働くとは思わない。 Bobbyは2009年12月25日に生まれ、現在の日付は2010年11月25日だと言っています。Bobbyはまだ1ではないので、技術的には0歳です。この状況では、DATEDIFFは日付の年の部分を調べているだけなので、計算は正しく行われません。 「datepart Boundaries」を参照してください:msdn.microsoft.com/en-us/library/ms189794.aspx – RayLoveless

0

閏年の代わりに365を使用しているため、元のソリューションは数日でオフになります。

関連する問題