使用参数

时间:2015-12-15 13:03:21

标签: c# sql sql-server

我的C#代码中有两个SQL语句来检索一些值。我知道他们对SQL注入是开放的,因为我没有使用参数,但我不确定我是否正确实现它们。

(注意:每个都在循环中循环数据表的行) 第一个例子:

string sql2 = "select max(day) as day from users u join days d on d.User_ID = u.id where u.ActiveUser = 1 and u.id = " + Users["ID"].ToString();
command.CommandText = sql2;               
string dt = command.ExecuteScalar().ToString(); 

在上面的语句中,它检索日期时间并将其分配给字符串dt。任何带有id或ID的东西都是bigint。

string sql = "SELECT MAX(Day) FROM Days WHERE Project_ID IN (SELECT ID FROM Projects WHERE Parent_ID = -1 AND ID = " + row["ID"] +  ") HAVING MAX(Day) < DATEADD(dd, -730, getdate())";
command.CommandText = sql;                                  
object val = command.ExecuteScalar();

上述语句与第一个语句相同,就像它检索日期时间值一样。任何带有id或ID的东西都是bigint。

这是我第一次提出的问题,我错过了什么或做错了什么?

string sql2 = "select max(day) as day from users u join days d on d.User_ID = u.id where u.ActiveUser = 1 and u.id = @userID";
using (conn)
{
     using (SqlCommand cmd = new SqlCommand(sql2, conn))
     {
          command.Parameters.AddWithValue("@userID", drUsers["ID"]);
          conn.Open();
          dt = (DateTime)command.ExecuteScalar();
     }
}

注意:我在上周就DateTime转换问了一个问题,但是有一个问题无法解决,所以我可能只需要使用返回的日期时间的字符串版本。这会影响到什么吗?

2 个答案:

答案 0 :(得分:3)

就像是:

string sql2 = @"select max(day) as day from users u 
join days d on d.User_ID = u.id 
where u.ActiveUser = 1 and u.id = @id";

string sql = @"SELECT MAX(Day) FROM Days 
WHERE Project_ID IN 
(SELECT ID FROM Projects WHERE Parent_ID = -1 AND ID = @id)
HAVING MAX(Day) < DATEADD(dd, -730, getdate())";

DateTime dt;
using (conn)
{
  using (SqlCommand cmd = new SqlCommand(sql2, conn))
  {
    cmd.Parameters.AddWithValue("@id", (Int64)Users["ID"]);
    conn.Open();
    dt = (DateTime)cmd.ExecuteScalar();
  }
}

using (conn)
{
  using (SqlCommand cmd = new SqlCommand(sql, conn))
  {
    cmd.Parameters.AddWithValue("@id", (Int64)row["ID"]);
    conn.Open();
    dt = (DateTime)cmd.ExecuteScalar();
  }
}

但是,出于性能原因,我不会在DataTable中每行执行一次此操作。您可以简单地将按ID分组的所有最大(日)值一次性地提供给客户端。即:

string sql = @"select u.Id, max(day) as day 
  from users u 
  join days d on d.User_ID = u.id 
  where u.ActiveUser = 1
  group by u.id";
编辑:我后来看到了您的编辑,以及有关日期时间的补充问题。不要将datetime值转换为字符串。这是错误开始的地方。如果你&#34;必须去&#34;然后只使用不受SQL服务器设置影响的ODBC规范格式 - yyyyMMdd。其他类型的日期时间字符串只会偶然发挥作用。

答案 1 :(得分:0)

string sql = @"select u.Id, max(day) as day 
  from users u 
  join days d on d.User_ID = u.id 
  where u.ActiveUser = 1
  group by u.id";

DataTable tbl = new DataTable();
using (conn)
{
  using (SqlCommand cmd = new SqlCommand(sql, conn))
  {
    conn.Open();
    tbl.Load( cmd.ExecuteReader() );
    conn.Close();
  }
}

var dates = tbl.AsEnumerable()
               .ToDictionary(t => t.Field<Int64>("ID"), 
                             t => t.Field<DateTime?>("Day"));

然后在你的循环中你可以说这样做:

var myId = 4;
var myDate = dates[myId];