2014-02-17 94 views
0

在我的VB.Net程序中,我發現兩條警告顯示以下消息:函數返回問題?

函數不會在所有代碼路徑上返回一個值。使用結果時,運行時可能會發生空引用異常

幫助我在哪裏解決問題並解決問題。以下快照是在警告錯誤表示:

而杉杉,因爲在異常警告附近「端功能」

'Executes SQL commands to the system database 
Public Function ExecSQL(ByVal sql As String) 
     Dim com As New MySqlCommand(sql) 
     Try 
      RefreshConnection() 
      com.Connection = con 
      com.ExecuteNonQuery() 
     Catch ex As Exception 
      Return ex 
      MsgBox(ex.Message, MsgBoxStyle.Critical, "Error") 
     End Try 
End Function 

第二華林近「端功能」

'Get the value of an specific field in a given sql string 
    Public Function GetField(ByVal sql As String, ByVal field As String) 
     Try 
      RefreshConnection() 
      Dim com As New MySqlCommand(sql, con) 
      Dim dReader As MySqlDataReader = com.ExecuteReader 

      While dReader.Read 
       GetField = dReader(field).ToString 
      End While 
      dReader.Close() 
     Catch ex As Exception 
      Return ex 
      MsgBox(ex.Message, MsgBoxStyle.Critical, "Error") 
     End Try 
    End Function 
+0

這段代碼有缺陷,在不相關的問題的重要途徑:它迫使你構建的方式SQL查詢,這將是可怕的脆弱到SQL注入攻擊。 **這實際上是乞求被黑客攻擊。** –

+0

另外:單一共享連接在.Net中不是最佳的。相反,.Net依賴於稱爲連接池的功能,因此在大多數情況下,您應該爲每次調用數據庫使用新的連接對象。真。相反,只需保持一個共享連接_string_便於創建連接。 –

+1

哦,並打開選項嚴格! –

回答

0

出現這種情況處理程序您實際返回異常對象ex。如果沒有發生異常,您不會返回任何內容。你可以明確地添加Return Nothing,只是在Catch ex as Exception之上,但我想從VB的消息中自動爲你做這個消息......

順便說一句:有什麼意思向調用者返回異常?將消息框放入呼叫方法中,並將您的呼叫包裝在Try-Catch那裏。顯然不打算與用戶交互的方法不應該顯示消息。然後,您可以將異常傳遞給最終的表示層。

長話短說:業務邏輯中沒有消息框。用戶信息只在表示層。


讀完第二種方法之後:這裏的情況更糟!如果數據讀取器有行,您可以將方法的結果設置爲您找到的最後一個(!)結果(這本身就是一個WTF,但是是另一個故事)。如果發生錯誤,結果是類型爲Exception的對象,因此調用代碼甚至需要確定函數調用的結果實際上是字段值還是異常!

這真是糟糕的設計我的朋友。


你問的固定碼:

'Executes SQL commands to the system database 
Public Sub ExecSQL(ByVal sql As String) 
    Dim com As New MySqlCommand(sql) 

    RefreshConnection() 
    com.Connection = con 
    com.ExecuteNonQuery() 
End Sub 

'Get the value of an specific field in a given sql string 
Public Function GetField(ByVal sql As String, ByVal field As String) 
    RefreshConnection() 
    Dim com As New MySqlCommand(sql, con) 
    Dim dReader As MySqlDataReader = com.ExecuteReader 

    GetField = Nothing 

    While dReader.Read 
     GetField = dReader(field).ToString 
    End While 
    dReader.Close() 
End Function 
+0

你能爲我編輯職位 –

+0

不,因爲那會使我的回答無效。我可以在我的答案中給你一個例子。 –

+0

所以我修復了你的代碼。請注意,現在主叫方必須處理例外情況。你應該*真的*花一分鐘的時間思考一下'while dReader.Read'是否正確。如果從數據庫中讀取多行,會發生什麼情況? –

0

有幾個缺點在這裏。在簡短起見,我將只是張貼一些改進代碼:

'Executes SQL commands to the system database 
Private Function ExecSQL(ByVal sql As String, ByVal params As IEnumerable(Of MySqlParameter)) 
    Using cn As New MySqlConnection(GetConnectionString()), _ 
      com As New MySqlCommand(sql, cn) 

     For Each param As MySqlParameter in params 
      com.Parameters.Add(param) 
     Next param 
     cn.Open() 
     com.ExecuteNonQuery() 
    End Using 
End Function 

'Get the value of an specific field in a given sql string 
Private Function GetField(Of T)(ByVal sql As String, ByVal params As IEnumerable(Of MySqlParameter), ByVal field As String) As T 
    Using cn As New MySqlConnection(GetConnectionString()) 
      com As New MySqlCommand(sql, cn) 

     For Each param As MySqlParameter In params 
      com.Parameters.Add(param) 
     Next param 
     cn.Open() 

     Using rdr As MySqlDataReader = com.ExecuteReader() 
      While rdr.Read() 
       Return CType(rdr(field), T) 
      End While 
     End Using 
    End Using 
    Return Nothing 
End Function