sql-server - 将日期保存到 SQL Server 表

标签 sql-server vb.net

我使用以下命令为变量设置日期值:

    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()

它有效,但我只能进行两次约会。之后我收到以下错误:

Conversion failed when converting date and/or time from character string

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

最佳答案

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

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

只有一种方法可以处理这个问题。 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 语句中的代码末尾销毁它

关于sql-server - 将日期保存到 SQL Server 表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34691610/

相关文章:

.net - 如何在vb.net中解析json数组?

vb.net - 如何转义双引号作为 NUnit TestCase 的参数?

html - Webbrowser 从动态组合框中选择值

asp.net - 子字符串的多个长度?

sql-server - 使用SMO .net通过DeviceType.Pipe进行备份和恢复

sql-server - SQL Server 日期时间转换失败

sql-server - 游标中的 sys.databases 跳过数据库

node.js - 连接到 (LocalDB)\MSSQLLocalDB Sequelize

c# - 如果从 Windows 服务执行,与 SQL Server 的连接失败

VB.NET - 可为空的日期时间和三元运算符