none
VB2008 連接至SQL資料庫的例外處理 RRS feed

  • 問題

  • 在爬文的時候偶然看到某位大大針對這個做了一個範例,所以小弟改了自己原本資料庫查詢的程式片段
     Dim STR As String = "Data Source=SONGDING\SQLEXPRESS;Initial Catalog=PLCALM;Integrated Security=True"
            Dim d1 As Date = DateTimePicker1.Value
            Dim d2 As Date = DateTimePicker2.Value
            Try
                Using conn As SqlConnection = New SqlConnection(STR)
                    Dim str1 As String = "select * from PC_REPORT where LOG_DAY BETWEEN @d1 AND @d2 ORDER BY NO "
                    If conn.State = ConnectionState.Closed Then
                        conn.Open()
                    End If
                    Using cmd As New SqlCommand(str1, conn)
                        cmd.Parameters.Add(New SqlParameter("@d1", SqlDbType.DateTime))
                        cmd.Parameters.Add(New SqlParameter("@d2", SqlDbType.DateTime))
                        cmd.Parameters("@d1").Value = d1
                        cmd.Parameters("@d2").Value = d2
                        Using OleDbda As New SqlDataAdapter(str1, conn)
                            Dim ds As DataSet
                            ds = New DataSet()
                            OleDbda.Fill(ds, "DataBank")
                            DataGridView1.DataSource = ds.Tables("DataBank")
                            Dim NUM As Integer = DataGridView1.RowCount
                            Label1.Text = "查詢筆數 :" + NUM
                            conn.Close()
                        End Using
                    End Using
                End Using 
            Catch dbex As SqlException
                Console.WriteLine(OleExInfo(dbex))
                MessageBox.Show(OleExInfo(dbex), "例外發生", MessageBoxButtons.OK, MessageBoxIcon.Error)
            Catch ex As Exception
                MessageBox.Show(OleExInfo(ex), "例外發生", MessageBoxButtons.OK, MessageBoxIcon.Error)
            End Try
    測到這裡喜憂參半..很高興自己對例外處理的方法多認識了一點!憂的是原本可行的程式到這就會跳出錯誤訊息來
    給的訊息是: Must declare the variable"@d1"
    字面上看來是變數使用上的問題..但小弟目前找不到原因~~
    請各位大大指導一下小弟!有哪邊錯誤的

    新手上路
    2009年7月24日 上午 11:30

解答

  • Dim STR As String = "Data Source=SONGDING\SQLEXPRESS;Initial Catalog=PLCALM;Integrated Security=True"
            Dim d1 As Date = DateTimePicker1.Value
            Dim d2 As Date = DateTimePicker2.Value
            Try
                Using conn As SqlConnection = New SqlConnection(STR)
                    Dim str1 As String = "select * from PC_REPORT where LOG_DAY BETWEEN @d1 AND @d2 ORDER BY NO "
                    If conn.State = ConnectionState.Closed Then
                        conn.Open()
                    End If
                    Using cmd As New SqlCommand(str1, conn)
                        cmd.Parameters.Add(New SqlParameter("@d1", SqlDbType.DateTime))
                        cmd.Parameters.Add(New SqlParameter("@d2", SqlDbType.DateTime))
                        cmd.Parameters("@d1").Value = d1
                        cmd.Parameters("@d2").Value = d2
                        Using OleDbda As New SqlDataAdapter(cmd) ' 直接傳 Command 物件給它就好了,否則它會在內部自己建一個 Command,你之前的參數宣告等於沒做。
                            Dim ds As DataSet
                            ds = New DataSet()
                            OleDbda.Fill(ds, "DataBank")
                            DataGridView1.DataSource = ds.Tables("DataBank")
                            Dim NUM As Integer = DataGridView1.RowCount
                            Label1.Text = "查詢筆數 :" + NUM
                            conn.Close()
                        End Using
                    End Using
                End Using 
            Catch dbex As SqlException
                Console.WriteLine(OleExInfo(dbex))
                MessageBox.Show(OleExInfo(dbex), "例外發生", MessageBoxButtons.OK, MessageBoxIcon.Error)
            Catch ex As Exception
                MessageBox.Show(OleExInfo(ex), "例外發生", MessageBoxButtons.OK, MessageBoxIcon.Error)
            End Try

    小人物一枚。
    • 已標示為解答 eblue 2009年7月24日 下午 02:06
    2009年7月24日 下午 12:48
    版主

所有回覆


  •    有一種可能是, 你的 DateTimePicker1 和 DateTimePicker2沒有指定Default值
       請在 Form Load 加上 DateTimePicker1.Value=Now() 和 DateTimePicker2.Value=Now()

    請關心自己的問題,不要問了就放空;這是對別人與自己的尊重
    2009年7月24日 上午 11:38
    版主
  • 我在想...我中斷看d1的值為  d1: #7/24/2009 7:46:26 PM# Date 但實際 LOG_DAY欄位格式值是:2009-07-23 12:00:00.000.也許是如此才造成這個問題吧.

    只是這樣要如何轉換..來去吃個飯~~吃飽再來想!!
    感謝大大的意見!!
    順便問一下大大 為何 DateTimePicker1.Value 他的值會是 #7/24/2009 7:46:26 PM#這種的..我的格式明明是選擇自訂了..

    新手上路
    • 已編輯 eblue 2009年7月24日 下午 12:03
    2009年7月24日 上午 11:57
  • 剛忘了說, 如果是SQL的話, 用 Parameters.AddWithValue 會比較方便

    請關心自己的問題,不要問了就放空;這是對別人與自己的尊重
    2009年7月24日 下午 12:01
    版主
  • Dim STR As String = "Data Source=SONGDING\SQLEXPRESS;Initial Catalog=PLCALM;Integrated Security=True"
            Dim d1 As Date = DateTimePicker1.Value
            Dim d2 As Date = DateTimePicker2.Value
            Try
                Using conn As SqlConnection = New SqlConnection(STR)
                    Dim str1 As String = "select * from PC_REPORT where LOG_DAY BETWEEN @d1 AND @d2 ORDER BY NO "
                    If conn.State = ConnectionState.Closed Then
                        conn.Open()
                    End If
                    Using cmd As New SqlCommand(str1, conn)
                        cmd.Parameters.Add(New SqlParameter("@d1", SqlDbType.DateTime))
                        cmd.Parameters.Add(New SqlParameter("@d2", SqlDbType.DateTime))
                        cmd.Parameters("@d1").Value = d1
                        cmd.Parameters("@d2").Value = d2
                        Using OleDbda As New SqlDataAdapter(cmd) ' 直接傳 Command 物件給它就好了,否則它會在內部自己建一個 Command,你之前的參數宣告等於沒做。
                            Dim ds As DataSet
                            ds = New DataSet()
                            OleDbda.Fill(ds, "DataBank")
                            DataGridView1.DataSource = ds.Tables("DataBank")
                            Dim NUM As Integer = DataGridView1.RowCount
                            Label1.Text = "查詢筆數 :" + NUM
                            conn.Close()
                        End Using
                    End Using
                End Using 
            Catch dbex As SqlException
                Console.WriteLine(OleExInfo(dbex))
                MessageBox.Show(OleExInfo(dbex), "例外發生", MessageBoxButtons.OK, MessageBoxIcon.Error)
            Catch ex As Exception
                MessageBox.Show(OleExInfo(ex), "例外發生", MessageBoxButtons.OK, MessageBoxIcon.Error)
            End Try

    小人物一枚。
    • 已標示為解答 eblue 2009年7月24日 下午 02:06
    2009年7月24日 下午 12:48
    版主
  • 在這段語法我修正如同大大提議的
     

     Using cmd As New SqlCommand(str1, conn)
                        'cmd.Parameters.Add(New SqlParameter("@d1", SqlDbType.DateTime))
                        'cmd.Parameters.Add(New SqlParameter("@d2", SqlDbType.DateTime))
                        cmd.Parameters.AddWithValue("@d1", DateTimePicker1.Value)
                        cmd.Parameters.AddWithValue("@d2", DateTimePicker2.Value)
                        Using OleDbda As New SqlDataAdapter(str1, conn)
    執行後的錯誤仍相同!
    我在檢查一下程式~~
    新手上路
    2009年7月24日 下午 01:22
  • 我也找到了那個問題!!多下了一次!!所以目前程式改成這樣
       Dim STR As String = "Data Source=SONGDING\SQLEXPRESS;Initial Catalog=PLCALM;Integrated Security=True"
            
            Try
                Using conn As SqlConnection = New SqlConnection(STR)
                    Dim str1 As String = "select * from PC_REPORT where LOG_DAY BETWEEN @d1 AND @d2 ORDER BY NO "
                    If conn.State = ConnectionState.Closed Then
                        conn.Open()
                    End If
                    Using OleDbda As New SqlDataAdapter(str1, conn)
                        OleDbda.SelectCommand.Parameters.AddWithValue("@d1", (DateTimePicker1.Text))
                        OleDbda.SelectCommand.Parameters.AddWithValue("@d2", (DateTimePicker2.Text))
                        Dim ds As DataSet
                        ds = New DataSet()
                        OleDbda.Fill(ds, "DataBank")
                        DataGridView1.DataSource = ds.Tables("DataBank")
                        Dim NUM As Integer = DataGridView1.RowCount
                        Label1.Text = "查詢筆數 :" + NUM
                        conn.Close()
                    End Using
                End Using
    
            Catch dbex As SqlException
                Console.WriteLine(OleExInfo(dbex))
                MessageBox.Show(OleExInfo(dbex), "例外發生", MessageBoxButtons.OK, MessageBoxIcon.Error)
            Catch ex As Exception
                'MessageBox.Show(OleExInfo(ex), "例外發生", MessageBoxButtons.OK, MessageBoxIcon.Error) '這裡會發生型別轉換的錯誤
            End Try
    把異常的地方先註解掉..可匯出資料表單了..例外的訊息也可以實際輸出了!! 只是不知為何會出現那個異常
    這是OleExInfo的程式碼..我是直接copy 余小章大大部落格裡的程式碼的!
     
    Private Function OleExInfo(ByVal ex As SqlException) As String
            Dim ErrInfo As String = ""
            For i As Integer = 0 To ex.Errors.Count - 1
                ErrInfo = "索引: " & i.ToString
                ErrInfo &= ControlChars.NewLine
                ErrInfo &= "錯誤說明: " & ex.Errors(i).Message
                ErrInfo &= ControlChars.NewLine
                ErrInfo &= "資料庫錯誤: " & ex.Errors(i).Number
                ErrInfo &= ControlChars.NewLine
                ErrInfo &= "提供者名稱: " & ex.Errors(i).Source
                ErrInfo &= ControlChars.NewLine
                ErrInfo &= "錯誤代碼:" & ex.Errors(i).State
                ErrInfo &= ControlChars.NewLine
            Next i
            Return ErrInfo
        End Function

    新手上路
    2009年7月24日 下午 01:46
  • 找到原因了是這裡
    Label1.Text = "查詢筆數 :" + NUM  ---> NUM 要轉成字串格式就好了....
    謝謝2位大大的協助!
    新手上路
    2009年7月24日 下午 02:05