从字符串转换datetime时转换失败

时间:2011-01-04 11:16:22

标签: c# sql-server-2005

我尝试从SQL Server 2005读取数据并将其填入TableAdapter(也尝试用户DataReader),但我不断收到此异常。 问题是我在某些系统上遇到了这个错误,那就是我在一个系统上运行我的应用程序,但是在另一个系统上我得到了这个例外。

守则是:

public DataSetRef GetReportPumpControl(PumpInfo pump, DateTime start, DateTime end)
    {
        if (!OpenConnection())
            return null;

        m_Command.CommandText = "SELECT ref_dig_pumpcontrol, ref_energy, ref_datetime FROM [molisoftSchema].[Refresh] WHERE ref_pump_id = " + pump.ID + " AND ref_datetime BETWEEN '" + start + "' AND '" + end + "' ORDER BY ref_datetime ASC";

        SqlDataAdapter adapter = new SqlDataAdapter(m_Command);
        DataSetRef ds = new DataSetRef();
        adapter.Fill(ds, "RefreshPC");

        return ds;

        /*m_Reader = m_Command.ExecuteReader();

        LinkedList<PumpControlInfo> returnValue = new LinkedList<PumpControlInfo>();
        while (m_Reader.Read())
        {
            PumpControlInfo tempControl = new PumpControlInfo();
            tempControl.DateTime = (DateTime)m_Reader["ref_datetime"];
            tempControl.Energy = (double)m_Reader["ref_energy"];
            tempControl.PumpControl = (bool)m_Reader["ref_dig_pumpcontrol"];

            returnValue.AddLast(tempControl);
        }
        m_Reader.Close();
        return returnValue.ToArray<PumpControlInfo>();*/
    }

请帮我解决这个问题。 提前谢谢!

2 个答案:

答案 0 :(得分:6)

用1石头杀死2只鸟并参数化你的SQL(将防止SQL注入攻击):

m_Command.CommandText = "SELECT ref_dig_pumpcontrol, ref_energy, ref_datetime FROM [molisoftSchema].[Refresh] WHERE ref_pump_id = @pumpid AND ref_datetime BETWEEN @StartDate AND @EndDate ORDER BY ref_datetime ASC";

m_Command.Parameters.AddWithValue("@pumpid", pump.ID);
m_Command.Parameters.AddWithValue("@StartDate", start);
m_Command.Parameters.AddWithValue("@EndDate", end);

问题是因为.NET开始和结束DateTime值被序列化为一个字符串,以“硬编码”到您生成的SQL中。但是,此字符串表示形式无法转换回SQL中的有效日期时间(您需要使用SAY日期格式,如yyyy-MM-ddTHH:mm:ss - 因此在附加到SQL语句之前显式格式化这些DateTimes) 。然而,参数化是解决这些问题的更好的解决方案。

答案 1 :(得分:1)

您应该将查询值设置为参数,而不是仅使用字符串连接(以及隐式转换)。尝试:

m_Command.CommandText = "SELECT ref_dig_pumpcontrol, ref_energy, ref_datetime FROM [molisoftSchema].[Refresh] WHERE ref_pump_id = @id AND ref_datetime BETWEEN @start AND @end ORDER BY ref_datetime ASC";
m_Command.Parameters.AddWithValue("@id", pump.ID);
m_Command.Parameters.AddWithValue("@start", start);
m_Command.Parameters.AddWithValue("@end", end);

除了总体上更好的练习外,这将在参数中使用转换属性,这些参数比隐式内联字符串转换更适合此类事物。