【问题标题】:Read data from sql database using datetime picker使用日期时间选择器从 sql 数据库中读取数据
【发布时间】:2013-02-02 08:54:26
【问题描述】:

如何使用 datetimepicker 值从数据库中读取数据。我的表单中有一个 datetimepicker 和一个 datagridview。我想使用选定的 datetimepicker 值从 Sql 数据库表中获取数据。我尝试使用此代码

Private Sub BTNFIND_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BTNFIND.Click
    getConnect()
    Dim editdate As String
    DTPEDITAT.Value= Format(DTPEDITAT.Value, "dd/MM/yyyy")
    editdate = DTPEDITAT.Value
    MessageBox.Show(editdate)
    Try
        Conn.Open()
        Dim strSQL As String = "SELECT EMP_ID,EMP_NAME,AT_STATUS,AT_REMARK FROM ATTENDANCE WHERE AT_DATE = '" & editdate & "' ORDER BY EMP_NAME ASC"
        Dim da As SqlDataAdapter = New SqlDataAdapter(strSQL, Conn)
        Dim ds As DataSet = New DataSet
        da.Fill(ds, "ATTENDANCE")
        Dim dt As DataTable = ds.Tables("ATTENDANCE")
        Dim row As DataRow
        Dim atstat As String
        For Each row In dt.Rows
            If row("AT_STATUS") = 1 Then
                atstat = "Present"
            ElseIf row("AT_STATUS") = 0 Then
                atstat = "Absent"
            ElseIf row("AT_STATUS") = 0.5 Then
                atstat = "Halfday"
            Else
                atstat = "Error"
            End If
            For x As Integer = 0 To ATCEDITGRID.Rows.Count - 1
                ATCEDITGRID.Rows(x).Cells(2).Value = row("EMP_ID")
                ATCEDITGRID.Rows(x).Cells(3).Value = row("EMP_NAME")
                ATCEDITGRID.Rows(x).Cells(0).Value = atstat
                ATCEDITGRID.Rows(x).Cells(1).Value = row("AT_REMARK")
            Next x
        Next row
    Catch ex As SqlException
        MsgBox(ex.Message, MsgBoxStyle.Critical, "SQL Error")
    Catch ex As Exception
        MsgBox(ex.Message, MsgBoxStyle.Critical, "General Error")
    End Try
End Sub

Datagridview 不显示任何东西也没有错误...

【问题讨论】:

    标签: vb.net sql-server-2005 datagridview datetimepicker


    【解决方案1】:

    我们每天都会在这里看到这些问题。它们源于同一个问题。

    切勿使用字符串连接来构建 SQL 查询。

    这是个大问题。当然你已经遇到了第一个效果。如何以可接受的方式将字符串转换为有效的数据类型?您需要解决底层数据库系统的嵌入式引号、正确的日期表示和十进制数字的解析问题。但是字符串连接的第二个也是更微妙的副作用是SQL Injection(这只是一个指导性链接,因为 SQL 注入是一个非常大的话题)

    要解决此类问题,唯一可接受的方法是使用 PARAMETERS。
    这意味着它是数据库引擎以有效的方式解决问题,您需要一个带有参数占位符(@something)的字符串和一个具有参数值的确切数据类型的参数集合。

    所以你的代码应该这样改变

    Dim strSQL As String = "SELECT EMP_ID,EMP_NAME,AT_STATUS,AT_REMARK " + 
                           "FROM ATTENDANCE WHERE AT_DATE = @editdate " + 
                           "ORDER BY EMP_NAME ASC"
    Using con = new SqlConnection("constring_here")
        con.Open()
        Using cmd = new SqlCommand(strSQL, con)
            cmd.Parameters.AddWithValue("@editdate", DTPEDITAT.Value)
            ' do whatever you want with the command '
            ' like ExecuteReader or use a DataAdapter to fill datasets'
        End Using
    End Using
    

    【讨论】:

    • +1 但 OP 的问题似乎是他想要一个简单的代码.. :D
    • @spajce 我不这么认为。简单总是更可取,但无错误应该是必须的。这样做是一个真正的坏习惯。当错误发生时,您不想发现自己脱下裤子。相信我,当您在潜在客户面前演示您的应用时,总会出现错误
    • 您的AT_DATE 列是文本字段(varchar、nvarchar)吗?如果是这样,您打算如何将 LIKE 语句应用于表示日期的字符串?在期间或特定日期之后搜索?这里有一个根本性的缺陷。日期应始终存储在 datetime 或 smalldatetime 列中,否则几乎不可能应用这种逻辑
    • @Steve- 此表格仅用于编辑特定日期的出勤情况。
    • 如果 AT_DATE 是 DateTime 列,则不能使用 LIKE。如果您只想要在 DateTimePicker 中选择的日期的人,请使用 = 和 DateTime 类型的参数(DateTimePicker.Value),如我的回答中所述。
    【解决方案2】:

    我的不推荐解决方案:

    删除括号和% 字符。在 ORDER 之前放置一个空格(尽管这不是您的语法错误的原因)。

    以这种方式修复选择:

    "SELECT EMP_ID,EMP_NAME,AT_STATUS,AT_REMARK FROM ATTENDANCE WHERE AT_DATE = '" & _
    editDate.ToString("yyyy-MM-dd hh:mm:ss") & _
    "' ORDER BY EMP_NAME ASC"
    

    我建议你是学习使用 SQL 参数

    查询应该如下所示(注意里面的@editDate 参数占位符):

    "SELECT EMP_ID,EMP_NAME,AT_STATUS,AT_REMARK FROM ATTENDANCE WHERE AT_DATE = @editDate ORDER BY EMP_NAME ASC".

    然后您只需将参数添加到SqlCommand。最简单的方法是使用SqlParameterCollection.AddWithValue

    yourSqlCommand.Parameters.AddWithValue("@editDate", editDate)

    完整示例:

        Dim editDate As Date = DTPEDITAT.Value
    
        Using conn As New SqlConnection(YOUR_CONNECTION_STRING_HERE)
            Using cmd As SqlCommand = conn.CreateCommand()
                cmd.CommandText = "SELECT EMP_ID,EMP_NAME,AT_STATUS,AT_REMARK FROM ATTENDANCE WHERE AT_DATE = @editDate ORDER BY EMP_NAME ASC"
                cmd.Parameters.AddWithValue("@editDate", editDate)
    
                adapter.SelectCommand = cmd
                adapter.Fill(ds)
    
                For Each row As DataRow In ds.Tables(0).Rows 
                    [do whatever with the result]
                Next
    
            End Using
            conn.Close()
        End Using
    

    来自MSDN关于Sql参数

    命令对象使用参数将值传递给 SQL 语句或 存储过程,提供类型检查和验证。不像 命令文本,参数输入被视为文字值,而不是 可执行代码。这有助于防范 “SQL 注入” 攻击,在 攻击者将命令插入到 SQL 语句中 危及服务器的安全性。除了安全 好处是,参数化命令提供了一种方便的方法来组织传递给数据源的值。

    【讨论】:

    • Dim editdate As Date editdate = DTPEDITAT.Value aditdate 不是来自数据库。只是一个 DateTimePicker 而已。
    • 如果你正在使用DateTimePicker.Value属性的这个字段,它的值已经是DateTime,并且你的数据库列是DateTime,然后忘记日期转换为字符串之类的东西,只需使用sql参数,直接在参数中添加日期时间值即可。
    • +1,其实这个答案是有道理的..:D,我只是在寻找一个直接的答案
    • @Thanzeem 你现在有一个完整的样本。试着告诉我们
    • @Thanzeem,史蒂夫先生已经解释了Parameters.AddWithValue
    【解决方案3】:

    尝试在您的"%) 附近移动一个空格,我更正了查询。试着弄清楚。

    Dim strSQL As String = "SELECT EMP_ID,EMP_NAME,AT_STATUS, " + _
         "AT_REMARK FROM ATTENDANCE " + _ 
         "WHERE Convert(Varchar(10), AT_DATE, 23) = " + _
         "('" & editdate.ToString("yyyy-MM-dd") & "') ORDER BY EMP_NAME ASC"
    

    【讨论】:

    • 谢谢你的朋友。感谢您的快速重播。但是另一个错误Convertion failed when converting datetime from character string
    • 我修改了我的答案.. 只需检查日期的正确格式
    • 检查我的答案.. 但要小心我的朋友。因为您的查询容易出现 sql-injection :)
    • 显示type Date is not a defined system type。但我将CAST(AT_DATE AS Date) 更改为CAST(AT_DATE AS DateTime)。现在没有显示任何错误。但没有得到任何数据。
    • 好的,试试把CAST(AT_DATE AS DateTime)改成Convert(Varchar(10), OrderDate, 23)
    【解决方案4】:

    我像这样更改我的代码

    Private Sub BTNFIND_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BTNFIND.Click
        ATCEDITGRID.Rows.Clear()
        getConnect()
        Dim editdate As String
        DTPEDITAT.Value = Format(DTPEDITAT.Value, "dd/MM/yyyy")
        editdate = DTPEDITAT.Value
        Try
            Conn.Open()
            Dim strSQL As String = "SELECT EMP_ID,EMP_NAME,AT_STATUS,AT_REMARK FROM ATTENDANCE WHERE AT_DATE = '" & editdate & "' ORDER BY EMP_NAME ASC"
            Dim da As SqlDataAdapter = New SqlDataAdapter(strSQL, Conn)
            Dim ds As DataSet = New DataSet
            da.Fill(ds, "ATTENDANCE")
            Dim dt As DataTable = ds.Tables("ATTENDANCE")
            Dim row As DataRow
            Dim atstat As String
            For Each row In dt.Rows
                If row("AT_STATUS") = 1 Then
                    atstat = "Present"
                ElseIf row("AT_STATUS") = 0 Then
                    atstat = "Absent"
                ElseIf row("AT_STATUS") = 0.5 Then
                    atstat = "Halfday"
                Else
                    atstat = "Error"
                End If
                Me.ATCEDITGRID.Rows.Add(row("EMP_ID"), row("EMP_NAME"), atstat, row("AT_REMARK"))
            Next row
            ATCEDITGRID.TopLeftHeaderCell.Value = "Sr.No."
            Me.ATCEDITGRID.RowHeadersDefaultCellStyle.Padding = New Padding(3)
            ATCEDITGRID.AllowUserToAddRows = False
            AddRowHeadersEdit()
            Conn.Close()
        Catch ex As SqlException
            MsgBox(ex.Message, MsgBoxStyle.Critical, "SQL Error")
        Catch ex As Exception
            MsgBox(ex.Message, MsgBoxStyle.Critical, "General Error")
        End Try
    End Sub
    

    Itz 工作良好....

    【讨论】:

      【解决方案5】:

      这是我的代码,它的工作原理

      oldbc.CommandText = "select * from recette where " & ComboBox1.Text & " between #" & DateTimePicker1.Text & "# and #" & DateTimePicker2.Text & "#"

      【讨论】:

        猜你喜欢
        • 2012-10-21
        • 2017-12-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多