2010-11-24 161 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 2010-11-24 16:14:50

+0

您的`(minAge!= 0 || maxAge!= 120)`子句很奇怪:唯一不允许的范围是0到120所以-1000到120是可以的; 0到999是可以的; 120到0是OK等等。 – LukeH 2010-11-24 16:19:06

+0

@LukeH。你能提供一些示例代码吗?请注意,我在数据库中的年龄并不像int ...我只有生日的datetime,我用它来计算他们的年龄。 – RayLoveless 2010-11-24 16:47:59

回答

0

就个人而言,我已经使用startDate.ToString("yy-MM-dd 00:00:00.000")endDate.ToString("yy-MM-dd 23:59:59.000")作品最好的(注意,在结束日期范围000中。出于某种原因,在我的经验,SQL关闭(可能是由于某种舍入误差的),当它涉及到的范围。

顺便说一句,你可以使用来自TimeSpan对象的静态方法时间计算。例如,TimeSpan.FromDays(...)

0

的问题可能与DateTime.Now,它考虑的时间以及日期。尝试用DateTime.Today代替它。

0

为什么不使用DateTime.AddYears方法。

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

insated的

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

的另一件事是:请不要使用字符串之间+运营商构建一个SQL查询,使用StringBuilder代替。

1

假设你正在使用SQL Server ...

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

它的价值 - 您的原始解决方案已关闭几天,因为它使用365而不是闰年会计。