2012-03-14 1 views
2

私は最初のプログラムを構築しようとしていますが、私はSQLにいくつか問題があります。Vb、SQL文のエラーです。それを理解することができません

私は、顧客や従業員(他の中でも)のデータベースを持っており、基本的なログイン画面を設定しようとしています。ユーザーはEmployeeID(プライマリキー)でログインします

このセクションでは、初めてログインする方法について説明します。

このIDを持つユーザーをデータベースでチェックし、パスワードを取得します。パスワードが空でない場合は、メッセージボックスが表示され、そこで停止します。

パスワードが空である場合は、新しいパスワードを確認して更新することを意味します。

これは私の理解が終わるところです。デバッグでは、SQLの更新プログラムに間違いがないことがわかりましたが、エラーは表示されません。

ヘルプ?

ありがとうございました。

コードは次のように:

Private Sub NewPass() 
    Dim PassCheck As String 
    GetDatabase() 
    'Check if there is a password 
    SQLString = "SELECT EmployeeID, Password, Deleted FROM Employee " 
    SQLString += "WHERE EmployeeID= " & UserID 
    Try 
     connection.Open() ' Open Connection 
     If ConnectionState.Open.ToString = "Open" Then 
      command = New System.Data.OleDb.OleDbCommand(SQLString, connection) 
      datareader = command.ExecuteReader() 
      If datareader.HasRows Then 
        If datareader.Item("Deleted") = False Then 
        'Password check 
        outputString = datareader.Item("Password").ToString 
        Else 
         outputString = "" 
        End If 
      End If 'recordset has rows 
      datareader.Close() 
     End If 
    Catch ex As Exception 'Display Error message 
     MessageBox.Show("Error accessing database", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) 
    End Try 
    connection.Close() 

    PassCheck = outputString 

    If String.IsNullOrEmpty(PassCheck) = True Then 

     GetDatabase() 
     SQLString = "UPDATE Employee SET " 
     SQLString += "Password = '" & Password & "' " 
     SQLString += "WHERE EmployeeID = " & UserID 
     'Try 
     connection.Open() 
     If ConnectionState.Open.ToString = "Open" Then 
      'Update Password 
      command = New System.Data.OleDb.OleDbCommand(SQLString, connection) 
      command.ExecuteNonQuery() 

      MainMenuForm.Show() 
      Me.Hide() 
     Else 
      outputString = "" 
      MessageBox.Show("Error opening connection") 
     End If 
     connection.Close() 
     'Catch ex As Exception 

     'End Try 
    Else 
     MessageBox.Show("This Account has a password", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) 
     FirstTimeButton.Show() 
     FirstTimeBool = False 
    End If 

End Sub 

GetDatabaseを()

Private Sub GetDatabase() 
    'Locates the Database 
    Try 
     ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data " 
     ConnectionString += "Source=" & System.Windows.Forms.Application.StartupPath & "\PharmacyDatabase.accdb " 
     connection = New System.Data.OleDb.OleDbConnection(ConnectionString) 
    Catch ex As Exception 'No Database Found 
     MessageBox.Show("No Database Found in \Debug", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) 
    End Try 
End Sub 
+1

これは、プレーンテキストのパスワードをデータベースに保存しているようですが、それは本当に悪い考えです。また、クエリがSQLインジェクション攻撃に対して脆弱であるように見えます。 –

+0

接続とは何ですか?それはどこに作られたのですか? GetDatabase()は何をしますか?また、 'ConnectionState.Open.ToString = "Open"は常にtrueと評価されます。 connection.ConnectionState == ConnectionState.Open –

+0

あなたのパスワード変数はこの関数の外に設定されていますか、更新SQL文を作成するときには何もありませんか? –

答えて

5

私は悪いニュースの無記名であることを憎むが、複数の深刻なセキュリティ上の問題を含め、そこだけそんなに間違ってあります潜在的なサービス拒否の脆弱性。以下のコードを試してみてください。あなたはここにbcryptのライブラリが利用できる必要があります
http://derekslager.com/blog/posts/2007/10/bcrypt-dotnet-strong-password-hashing-for-dotnet-and-mono.ashx

まず、新しいGetDatabase()関数:

Private Function GetDatabase() As OleDbConnection 
    Return New System.Data.OleDbOleDbConnection(string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0}\PharmacyDatabase.accdb", System.Windows.Forms.Application.StartupPath)) 
End Function 

それは直感的だが、それを接続プールのおかげで、本当にネットで優れています毎回新しい接続を作成します。

その後

、主な機能:

Private Sub NewPass() 
    Dim sql As String = "UPDATE Employee SET Password = ? WHERE EmployeeID= ? AND Password IS NULL" 
    Dim resultCount As Integer 
    Using cn As System.Data.OleDb.OleDbCommand = GetDatabase(), _ 
      command As New System.Data.OleDb.OleDbCommand(sql, cn) 

     command.Parameters.Add("Password", OleDbType.Char, 60).Value = BCrypt.HashPassword(password, BCrypt.GenerateSalt(12)) 
     command.Parameters.Add("UserID", OleDbType.Integer).Value = UserId 

     cn.Open() 
     resultCount = command.ExecuteNonQuery() 
    End Using 

    If resultCount <> 1 Then 
     'If a password was already set (password field not null), resultCount will be zero 
     MessageBox.Show("This Account does not exist or already has a password", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) 
     FirstTimeButton.Show() 
     FirstTimeBool = False 
    Else 
     MainMenuForm.Show() 
     Me.Hide() 
    End If 

End Sub 

あり、完全に欠落しているそのコードにはいくつかのものがあり、それらはどこに行ったので、私は説明したいです。最初は、connection.Close()がないということです。これは、Usingブロックによって完全に処理され、Useブロックは例外がスローされても接続が閉じられることを保証するため、処理が改善されました。

次はTry/Catchブロックです。私の気持ちは、エラーをチェックするコードのレベルが間違っているということです。例外に関する素晴らしいことは、彼らが積み重ねることです。通常は、UIに近いコードのtry/catchを保存する方が良いです。これは、通常、どのように対処するかを知る上でより良い立場にあるからです。したがって、データベースと直接交信するコードでは、例外が発生するだけで、ビジネスレイヤーまたはプレゼンテーションレイヤーはその例外処理を行うことができます。

最終的な欠落部分は、接続状態のチェックです。接続状態の確認は、エラーから回復しようとしている場合、または単に開いたままにしておきたい長期接続がある場合は、例外ハンドラでのみ必要です。すでに述べたように、このレベルのコードはエラー処理のための適切な場所であるとは思えず、.Netは短い接続でよりうまくいくので、これを完全にスキップできます。

+0

私は経験のないvb/sqlで信じられないほど基本的な最初の試みとしてこれを使用しています。それは重要ではないので、パスワードはそうです。私は今、テーブルを適切に更新することを学ぶことだけに気を配っています。 – PatPat

+0

これは本当に役に立ちます。ありがとうございました。私は別の日のBCryptの探査を残すかもしれませんが。 – PatPat

+0

それでは、後で参照できるように、パスワードの部分を心の裏に置いてください。このコードの残りの部分には、接続ブロック、クエリパラメータ、ExecuteNonQueryおよび戻り値を閉じるためにUsingブロックを利用するなど、重要なことがたくさんあります。短期間で.Open()を呼び出した後に接続状態を確認する必要はありません。接続などが含まれます。 –

0

あなたはUPDATE文の一部として、あなたのコードに次き:

SQLString += "Password = '" & Password & "' " 

あなたはPasswordという名前の変数を持っているところが、私は表示されません。 PassCheckが表示されますが、Passwordはありません。

+0

パスワードはクラスの先頭に文字列として、UserID(整数として)と宣言されています。それはNewPass()に利用可能です。 – PatPat

関連する問題