在SQL Server中比较日期时出错

时间:2016-04-20 08:38:44

标签: sql-server vb.net datetime

我正在编写此程序,用户将输入开始日期和结束日期。然后程序将从数据库中检索记录,其中db中的startdate将是> =用户输入开始日期,db中的enddate将是< =用户输入结束日期。

Dim dateStr As DateTime = dtpStart.Value
Dim dateEnd As DateTime = dtpEnd.Value

MsgBox(dateStr)

con.ConnectionString = "Data Source=MKZSA065\SQLSERVER2008R2,1499;Initial Catalog=inv"
con.Open()
MsgBox("server connected")

cmd.Connection = con
'cmd.CommandText = "Select column_name as 'Columnname', data_type as'Datatype' from information_schema.columns where table_name = 'inv.dbo.InOutTransaction' AND column_name = 'inv.dbo.InOutTransaction.startDate'"
'cmd.CommandText = "Select inv.dbo.InOutTransaction.refNo, inv.dbo.Case_Status.deployedBy, CONVERT(varchar(10), inv.dbo.InOutTransaction.startDate, 120) as startDate, CONVERT(varchar(10), inv.dbo.InOutTransaction.endDate, 120) as endDate, inv.dbo.InOutTransaction.item FROM inv.dbo.InOutTransaction inner join inv.dbo.Case_Status ON inv.dbo.InOutTransaction.refNo = inv.dbo.Case_Status.refNo WHERE inv.dbo.InOutTransaction.refNo LIKE 'L%' AND inv.dbo.InOutTransaction.status LIKE 'Out'"

cmd.CommandText = "Select inv.dbo.InOutTransaction.refNo, inv.dbo.Case_Status.deployedBy, CONVERT(varchar(10),inv.dbo.InOutTransaction.startDate,120) as startDate, CONVERT(varchar(10),inv.dbo.InOutTransaction.endDate,120) as endDate, inv.dbo.InOutTransaction.item from inv.dbo.InOutTransaction inner join inv.dbo.Case_Status ON inv.dbo.InOutTransaction.refNo = inv.dbo.Case_Status.refNo WHERE inv.dbo.InOutTransaction.refNo LIKE 'L%' AND inv.dbo.InOutTransaction.status LIKE '%Out%' AND inv.dbo.InOutTransaction.startDate >= '" & dateStr & "' AND inv.dbo.InOutTransaction.endDate <= '" & dateEnd & "'"

Dim lrd As SqlDataReader
Dim li As ListViewItem

lrd = cmd.ExecuteReader()

Dim num As Integer = 1
While lrd.Read()
    ListView1.BeginUpdate()

    li = ListView1.Items.Add(num.ToString)
    li.SubItems.Add(lrd("refNo").ToString)
    li.SubItems.Add(lrd("deployedBy").ToString)
    li.SubItems.Add(lrd("startDate").ToString)
    li.SubItems.Add(lrd("endDate").ToString)
    li.SubItems.Add(lrd("item").ToString)
    'li.SubItems.Add(lrd("column_name").ToString)
    'li.SubItems.Add(lrd("data_type").ToString)

    num += 1

    ListView1.EndUpdate()
    ListView1.EnsureVisible(ListView1.Items.Count - 1)
End While

发生了错误

  

从字符串转换日期时间

时转换失败

我该怎么做,怎么做:(

2 个答案:

答案 0 :(得分:3)

<强> USE PARAMETERISED QUERIES

很抱歉大喊大叫,但我不能强调这是多么重要,不仅仅是为了解决你的错误,而是为了一般性能和安全性。

所以而不是

"inv.dbo.InOutTransaction.startDate >= '" & dateStr & "' AND inv.dbo.InOutTransaction.endDate <= '" & dateEnd & "'"

您需要使用

"inv.dbo.InOutTransaction.startDate >= @StartDate AND inv.dbo.InOutTransaction.endDate <= @EndDate"

然后将参数添加到SqlCommand:

cmd.Parameters.Add("@StartDate", SqlDbType.DateTime).Value = dateStr
cmd.Parameters.Add("@EndDate", SqlDbType.DateTime).Value = dateEnd 

这意味着不需要任何隐式转换,您的SqlCommand需要两个日期参数,并且您传递两个DateTime对象。突然之间,日期的格式和文化差异是无关紧要的。此外,这意味着SQL Server可以使用缓存计划,并且不需要为传递的每个不同的开始和结束日期值重新编译查询。

另外,在处理Using对象时使用IDisposable是个好主意,特别是对于像这样的非托管对象。所以你最终会得到类似的东西:

Dim dateStr As DateTime = dtpStart.Value
Dim dateEnd As DateTime = dtpEnd.Value

Dim sql as String = "Select inv.dbo.InOutTransaction.refNo, " & _
                    "       inv.dbo.Case_Status.deployedBy, " & _
                    "       CONVERT(varchar(10), " & _
                    "       inv.dbo.InOutTransaction.startDate,120) as startDate,  " & _
                    "       CONVERT(varchar(10),inv.dbo.InOutTransaction.endDate,120) as endDate,  " & _
                    "       inv.dbo.InOutTransaction.item  " & _
                    "from inv.dbo.InOutTransaction "
                    "   inner join inv.dbo.Case_Status  " & _
                    "       ON inv.dbo.InOutTransaction.refNo = inv.dbo.Case_Status.refNo  " & _
                    "WHERE inv.dbo.InOutTransaction.refNo LIKE 'L%'  " & _
                    "AND inv.dbo.InOutTransaction.status LIKE '%Out%'  " & _
                    "AND inv.dbo.InOutTransaction.startDate >= @StartDate  " & _
                    "AND inv.dbo.InOutTransaction.endDate <= @EndDate"


Using con As new SqlConnection("Data Source=MKZSA065\SQLSERVER2008R2,1499;Initial Catalog=inv;User ID=inv_admin;Password=inv_admin123")
Using cmd As New SqlCommand(sql, con)

    con.Open()
    cmd.Parameters.Add("@StartDate", SqlDbType.DateTime).Value = dateStr
    cmd.Parameters.Add("@EndDate", SqlDbType.DateTime).Value = dateEnd 

    Using lrd As SqlDataReader = cmd.ExecuteReader()

        Dim num As Integer = 1
        Dim li As ListViewItem

        While lrd.Read()
            ListView1.BeginUpdate()

            li = ListView1.Items.Add(num.ToString)
            li.SubItems.Add(lrd("refNo").ToString)
            li.SubItems.Add(lrd("deployedBy").ToString)
            li.SubItems.Add(lrd("startDate").ToString)
            li.SubItems.Add(lrd("endDate").ToString)
            li.SubItems.Add(lrd("item").ToString)
            'li.SubItems.Add(lrd("column_name").ToString)
            'li.SubItems.Add(lrd("data_type").ToString)

            num += 1

            ListView1.EndUpdate()
            ListView1.EnsureVisible(ListView1.Items.Count - 1)
        End While
    End Using
End Using

请原谅我的vb.Net,如果它出现了错误,我很久没有使用它了,所以至少可以说是生锈的,希望它足以说明问题

答案 1 :(得分:0)

我认为datestr是本地格式。 无论DATEFORMAT设置如何,都使用格式YYYYMMDD。

相关问题