转换错误

时间:2012-10-05 08:51:44

标签: c# sql parameters

有人可以告诉我为什么我得到以下错误,当我运行我的代码时,我不确定它是否与我的sql语句有问题,因为这似乎没问题,但我在下面添加它以便我可以得到第二意见

“从字符串转换日期/时间时转换失败”

public static int GetConveyorProductionCount(string machineNameV, string StartTimeV, string EndTimeV)
    {

        try
        {
            int count;

            SqlParameter param01 = new SqlParameter("@param01", SqlDbType.VarChar, 5);
            param01.Value = machineNameV;

            SqlParameter param02 = new SqlParameter("@param02", SqlDbType.VarChar, 5);
            param02.Value = StartTimeV;

            SqlParameter param03 = new SqlParameter("@param03", SqlDbType.VarChar, 5);
            param03.Value = EndTimeV;

            SqlCommand getConveyorProductionSC = new SqlCommand("SELECT cast([" + machineNameV + "] as int) FROM VWCONVEYORPRODUCTION WHERE([DA_TE] BETWEEN @param02 AND @param03)", myConnection);

            getConveyorProductionSC.Parameters.Add(param01);
            getConveyorProductionSC.Parameters.Add(param02);
            getConveyorProductionSC.Parameters.Add(param03);

            myConnection.Open();
            object result = getConveyorProductionSC.ExecuteScalar();
            myConnection.Close();

            if (result == DBNull.Value)
            {
                count = 0;
            }
            else
            {
                count = Convert.ToInt32(result);
            }

            return count;
        }
        catch (Exception e)
        {
            throw new Exception("Error retrieving the Conveyor production count. Error: " + e.Message);
        }

3 个答案:

答案 0 :(得分:5)

除了此代码的大量其他问题

SqlParameter param02 = new SqlParameter("@param02", SqlDbType.DateTime);
param02.Value = StartTimeV;
SqlParameter param03 = new SqlParameter("@param03", SqlDbType.DateTime);
param03.Value = EndTimeV;

将是一个良好的开端 当然假设表中的DA_TE列是日期时间? 当然,您还需要将它们作为DateTimes传递

我确实赞扬你使用参数化查询。

如果是我,我的代码看起来像

public static int GetConveyorProductionCount(string machineNameV, DateTime StartTimeV, DateTime EndTimeV)
{
  {
  using (SqlConnection connection = new SqlConnection(myConnectionString))
  {
    connection.Open();
    using(SqlCommand command = new SqlCommand(String.Format(CultureInfo.InvariantCulture, "SELECT cast([{0}] as int) FROM VWCONVEYORPRODUCTION WHERE([DA_TE] BETWEEN @StartDate AND @EndDate)", machineNameV), connection);            
    {
      command.Parameters.AddWithValue("StartDate",StartTimeV);
      command.Parameters.AddWithValue("EndDate",EndTimeV);
      object result = command.ExecuteScalar();
      if (result == DBNull.Value)
      {
        return 0;
      }
      else
      {
        return (Int32)result;
      }
    }
  }
}

你创建的任何一个实现IDisposable的苍蝇放入一个使用区块。

除非您正在执行显式事务,或者关闭了连接缓存,否则不要保留Ado.Net数据库连接。

将DateTimes传递为DateTimes

给你的变量一个不错的名字,param02并不意味着什么,而且计数是误导性的。

在您需要之前不要创建东西

你做的事情是例外 我个人不会费心陷入这段代码,特别是在抛弃有关异常的所有有用细节之后再次抛出它。

如果你想这样做,请定义一个CustomException,然后执行 抛出新的MyCustomException(“检索传送带生产计数时出错。”,e);

这样我们就可以在需要的时候捕获这个特定的异常,但是你将拥有整个异常链和所有堆栈跟踪。

最后但并非最不重要的是对待包括我在内的所有编码示例,好像它们是由村里白痴厚厚的堂兄建造的。 :d

答案 1 :(得分:1)

我的理论是,作为DateTime传递的字符串格式不正确。

看一下下面的例子

SQL Fiddle DEMO of working value

SQL Fiddle DEMO of broken value

使用 01 Ja 2012 的第二个示例(注意 Ja 而不是 Jan )会产生错误消息

  

从字符转换日期和/或时间时转换失败   串

答案 2 :(得分:1)

我认为你的问题是你的VWCONVEYORPRODUCTION表中的DA_TE列是一个sql日期类型。所以这意味着你的参数也应该是日期类型。

public static int GetConveyorProductionCount(string machineNameV, DateTime StartTimeV, DateTime EndTimeV)
    {
    enter code here
        try
        {
            int count;

            SqlParameter param01 = new SqlParameter("@param01", SqlDbType.VarChar, 5);
            param01.Value = machineNameV;

            SqlParameter param02 = new SqlParameter("@param02", SqlDbType.date);
            param02.Value = StartTimeV;

            SqlParameter param03 = new SqlParameter("@param03", SqlDbType.date);
            param03.Value = EndTimeV;

            SqlCommand getConveyorProductionSC = new SqlCommand("SELECT cast([" + machineNameV + "] as int) FROM VWCONVEYORPRODUCTION WHERE([DA_TE] BETWEEN @param02 AND @param03)", myConnection);

            getConveyorProductionSC.Parameters.Add(param01);
            getConveyorProductionSC.Parameters.Add(param02);
            getConveyorProductionSC.Parameters.Add(param03);

            myConnection.Open();
            object result = getConveyorProductionSC.ExecuteScalar();
            myConnection.Close();

            if (result == DBNull.Value)
            {
                count = 0;
            }
            else
            {
                count = Convert.ToInt32(result);
            }

            return count;
        }
        catch (Exception e)
        {
            throw new Exception("Error retrieving the Conveyor production count. Error: " + e.Message);
        }

如果在调用此函数之前需要将字符串转换为DateTimes,请使用DateTime.ParseExact()