【问题标题】:Selecting SQL DateTime with C# DateTime variable使用 C# DateTime 变量选择 SQL DateTime
【发布时间】:2016-09-28 08:22:07
【问题描述】:

我正在尝试运行从包含 DateTime 的表中选择所有内容的查询。在 DateTime,它使用 DateTime 变量(通过参数传递的参数),但是它给了我这个例外:

"FormatException 未处理 mscorlib.dll 中出现“System.FormatException”类型的未处理异常 附加信息:该字符串未被识别为有效的日期时间”

我尝试过但不起作用的解决方案:

  • 将 DateTime 转换为字符串
  • 将 DateTime 转换为格式正确的字符串,然后返回 再次日期时间
  • 使用 DateTime.Parse 方法
  • 使用格式正确的 DateTime.ParseExact 方法并同时使用 "CultureInfo.InvariantCulture" 和 "CreateSpecificCulture("zh-CN")
  • 将格式更改为与运行查询时显示的完全相同的格式 数据库

如前所述,以上都没有奏效..

  • 我尝试使用的格式:“MM/dd/yyyy 00:00:00”
  • 在数据库中运行查询时显示的格式:“MM/dd/yyyy hh:mm:ss:fff"(时间需要设置为00:00:00)

以下是排除连接内容的代码:

cmd = new SqlCommand("SELECT * FROM Arithmetics "
                    + "INNER JOIN ArithmeticsAndTypeIDs "
                    + "ON Arithmetics.ArithmeticID = ArithmeticsAndTypeIDs.ArithmeticsID "
                    + "INNER JOIN ArithmeticTypes "
                    + "ON ArithmeticsAndTypeIDs.TypeID = ArithmeticTypes.TypeID "
                    + "WHERE UserID = @value1 "
                    + "AND TimeStamp >= '@value2' "
                    + "AND TimeStamp <= '@value3'", con);
                cmd.Parameters.AddWithValue("@value1", GetUserID(userLoggedIn));
                cmd.Parameters.AddWithValue("@value2", DateTime.ParseExact(time.ToString(), formatString, CultureInfo.CreateSpecificCulture("en-GB").DateTimeFormat));
                time = time.AddDays(1);
                cmd.Parameters.AddWithValue("@value3", DateTime.ParseExact(time.ToString(), formatString, CultureInfo.CreateSpecificCulture("en-GB").DateTimeFormat));

问题首先出现在以下行:"+ "AND TimeStamp >= '@value2' ""

* 如果有什么不同,这里是我在数据库中使用的 obv 引用。有效(用占位符值替换变量)

    SELECT * FROM Arithmetics
    INNER JOIN ArithmeticsAndTypeIDs 
    ON Arithmetics.ArithmeticID = ArithmeticsAndTypeIDs.ArithmeticsID
    INNER JOIN ArithmeticTypes 
    ON ArithmeticsAndTypeIDs.TypeID = ArithmeticTypes.TypeID
    WHERE UserID = 0
    AND
    ArithmeticTypes.TypeID = 2
    AND TimeStamp >= '09-21-2016 00:00:00'
    AND TimeStamp <= '09-22-2016 00:00:00'

应该注意“@value2”包含值(“09-21-2016 00:00:00”)(假设这是作为参数传递的日期),所以我知道格式正确。

我们将不胜感激任何解决此问题的帮助:)

【问题讨论】:

  • 删除 '@value2' 中的单引号 ' => "AND TimeStamp &gt;= @value2 "。在@value3 中也有
  • 在参数占位符周围添加单引号将其转换为文字字符串,当然没有办法将字符串“@value1”视为日期
  • 哦,所以它正在尝试将“@value2”转换为日期时间?现在看起来很合乎逻辑......谢谢!我怎样才能在不打开 SQL 注入的情况下解决这个问题?
  • 没错,斯普鲁兹。使用参数时,不需要加引号,让参数变魔术
  • @Sprouze 你不需要转换任何东西,无论是参数名称还是值。参数值由驱动程序作为二进制值传递。只需按原样传递time

标签: c# mysql database datetime formatting


【解决方案1】:

您不需要将参数转换为字符串。这是使用它们而不是字符串连接的主要原因之一。只要TimeStamp 是与日期相关的类型,您的查询应该是:

WHERE UserID = @value1 AND TimeStamp BETWEEN @value2 and @value3

参数值应该在不转换为字符串的情况下传递:

cmd.Parameters.AddWithValue("@value1", GetUserID(userLoggedIn));
cmd.Parameters.AddWithValue("@value2", time);
cmd.Parameters.AddWithValue("@value3", time.AddDays(1));

驱动程序本身以二进制形式传递参数,因此不必将它们转换为文本。这样您就可以绕过任何格式或本地化问题。

您还可以避免 SQL 注入问题,因为参数值绝不是查询的一部分。甚至字符串变量也被视为文本,它们绝不是查询的一部分。

【讨论】:

    猜你喜欢
    • 2020-02-03
    • 1970-01-01
    • 2020-05-22
    • 1970-01-01
    • 1970-01-01
    • 2018-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多