【问题标题】:Save date to SQL Server table将日期保存到 SQL Server 表
【发布时间】:2023-04-08 05:32:01
【问题描述】:

我正在使用以下方法将日期值设置为变量:

    Dim someDate As DateTime = Date.Today.AddDays(1) 

    nextMonday = someDate
    While nextMonday.DayOfWeek <> DayOfWeek.Monday
        nextMonday = nextMonday.AddDays(1)
    End While

然后我使用以下命令将日期插入到 SQL Server 表中:

   Private Sub CButton1_ClickButtonArea(Sender As Object, e As MouseEventArgs) Handles CButton1.ClickButtonArea
    Dim doenditstring As String = "INSERT INTO Parsversoeke (ma_datum,di_datum)  " & _
                                     "VALUES (" & _
                                       "'" & nextMonday & "'," & _
                                     "'" & nextTuesday & "')" 

    cnn.Open()
    Dim aksie As New SqlClient.SqlCommand(doenditstring, cnn)

    aksie.ExecuteNonQuery()

    cnn.Close()

它有效,但我只能在两个日期内完成。之后我收到以下错误:

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

有人知道我为什么会收到错误消息吗?

【问题讨论】:

  • 我对 vb.net 了解不多(我认得),但是在执行它们之前,您可以将它们打印到控制台(或以某种方式记录它们吗?)。您的日期最好采用YYYY-MM-DDYYYYMMDD 格式(ISO 8601 方式)。
  • SQL Injection alert - 您应该将您的 SQL 语句连接在一起 - 使用 参数化查询 来避免 SQL 注入。并且作为副作用,当尝试以字符串文字形式插入日期时,这也解决了那些令人讨厌的格式问题(多一个或少一个单引号等)....

标签: sql-server vb.net


【解决方案1】:

不,这种连接字符串的方法从一开始就注定要失败。
您会收到语法错误、转换错误,可能还有Sql Injection Attacks

  • 语法错误:严格来说不是你的情况,但如果一个字符串用作 一个值包含一个单引号,然后是整个连接的字符串 语法无效
  • 转换错误:您不必担心如何准备数据以 可以作为数据库的输入。小数呢 分隔符?您应该使用点还是逗号?这取决于语言环境 数据库的设置,如果它在不同的文化中 代码将很快变得一团糟,充满无用的替换或 ToString
  • Sql 注入:同样,这里没有严格涉及,但采取任何措施 由您的用户键入并将其直接用作查询的一部分是 真的是一个很大的错误,可能会给您的客户带来很多损失。见 上面的链接

只有一种方法可以处理这个问题。 Parameterized queries

Private Sub CButton1_ClickButtonArea(Sender As Object, e As MouseEventArgs) Handles CButton1.ClickButtonArea
    Dim doenditstring As String = "INSERT INTO Parsversoeke " & _
                                  "(ma_datum,di_datum)  " & _
                                  "VALUES (@m, @t)"

    cnn.Open()
    Dim aksie As New SqlClient.SqlCommand(doenditstring, cnn)
    aksie.Parameters.Add("@m", SqlDbType.Date).Value = nextMonday     
    aksie.Parameters.Add("@t", SqlDbType.Date).Value = nextTuesday 
    aksie.ExecuteNonQuery()
    cnn.Close()
End Sub

在您的代码中,您要求编译器将您的 DateTime 变量转换为字符串并执行请求的任务,但它不知道该字符串将执行 sql 命令。当然,您可以使用 ToString 和格式给它一个强有力的提示,但是您押注于数据库本身能够根据其转换规则将该字符串转换回数据时间。最后,为什么要允许所有这些转换?参数可以让你的代码从这些混乱中解脱出来。

现在请注意,您的命令文本如何更加清晰,正确传递值的工作由 ADO.NET 引擎本身(及其 SqlClient 类)完成,该引擎更了解如何为您的数据库准备 DateTime 变量。

我还应该解决从您的代码中清晰可见的另一个问题。有一个全局连接对象,可在您需要时重用。这是一种不好的做法,因为您永远无法确定该对象的正确状态。如果在某个地方,在这段代码之前,你发现了一个异常,结果你的连接仍然是打开的?你再次打开它,你会得到一个新的异常。同样,您的程序将很快突然结束。此外,这些对象包含非托管资源,如果不释放这些资源,将在程序中的任何地方造成问题。我建议在每次需要时创建一个新的 SqlConnection,并确保在代码末尾将其销毁,并将其包含在 Using 语句中

【讨论】:

    猜你喜欢
    • 2023-03-30
    • 1970-01-01
    • 2014-08-03
    • 1970-01-01
    • 1970-01-01
    • 2013-08-28
    • 2016-11-29
    • 1970-01-01
    • 2014-08-09
    相关资源
    最近更新 更多