我使用以下内容为变量设置日期值:
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()
它有效,除了我只能在两个日期做.之后我收到以下错误:
从字符串转换日期和/或时间时转换失败
有谁知道我为什么会收到错误?
不,这种连接字符串的方法从一开始就注定要失败.
您会收到语法错误,转换错误以及可能的Sql注入攻击.
语法错误:严格来说不是这种情况,但如果用作值的字符串包含单引号,则整个连接字符串在语法上无效
转换错误:您不必担心如何准备数据作为数据库的输入.十进制分隔符怎么样?你应该使用一个点还是一个逗号?它取决于数据库的区域设置,如果它位于不同的文化中,您的代码将很快变成一堆乱七八糟的替换或ToString
Sql注入:同样,这里没有严格的参与,但是接受用户输入的任何内容并直接将其用作查询的一部分实际上是一个很大的错误,可能会给您的客户带来很多损失.请参阅上面的链接
只有一种方法可以解决这个问题.参数化查询
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语句中