2016-11-13 18 views
1

私はvb.netでデータベースアクセスを教え始めました。私はthis as a referenceを使っています。私のMS Accessデータベースは、私がリレーショナルデータベースをセットアップして以来、私の参照が通過する例より少し複雑です。私は2つのテーブルを持っています。プレイヤーと、村。各プレイヤーは1つ以上の村(1対多数の関係)を持つことができます。この関係は、プレイヤーIDとプレイヤーIDの間で結ばれ、村の所有者を定義するために村のテーブルで使用されます。新しいプレイヤーをデータベースに追加する方法は次のとおりです。MS Accessのオートナンバー型フィールドとVB.netの問題

Public Sub NewPlayer(ByVal playerName As String) 
    Dim playerID As Integer = getLastIdent("Players") + 1 
    Dim tmpnum As Integer = playerID 

    Dim dsNewRow As DataRow 
    Dim Sql As String 

    Sql = "SELECT * FROM Players" 

    da = New OleDb.OleDbDataAdapter(Sql, con) 
    da.Fill(ds, "Players") 

    Dim cb As New OleDb.OleDbCommandBuilder(da) 

    dsNewRow = ds.Tables("Players").NewRow() 

    dsNewRow.Item("ID") = playerID 
    dsNewRow.Item("NameP") = playerName 
    dsNewRow.Item("Coins") = 0 


    ds.Tables("Players").Rows.Add(dsNewRow) 

    da.Update(ds, "Players") 

    Call NewVillage(playerName, playerID) 
End Sub 

getLastIdentサブルーチンは、プレーヤーIDフィールドで最後に使用された値を検索しようとしました。

Public Function getLastIdent(ByVal tblname As String) 
    Dim sql As String = "SELECT @@IDENTITY FROM " & tblname 
    Dim cmd As New OleDb.OleDbCommand(Sql, con) 
    Return cmd.ExecuteScalar() 
End Function 

しかし、これは全く機能しません(何があっても0を返します)。選手たちは、実際には滞りなく作成することができます(間違ったID番号が正しくオートナンバーをインクリメントするデータベースでいくつかの点で自分自身を修正するようだが、私はNewVillageを実行する新しいプレーヤーに村を割り当てること;。

Public Sub NewVillage(ByVal playerName As String, ByVal playerID As Integer) 
    Dim numVils As Integer = getVilCount() 
      Dim xpos As Integer 
    Dim ypos As Integer 
    xpos = CInt(Rnd()*50) 
    ypos = CInt(Rnd()*50) 


    Dim dsNewRow As DataRow 
    Dim Sql As String 

    Sql = "SELECT * FROM Villages" 

    da = New OleDb.OleDbDataAdapter(Sql, con) 
    da.Fill(ds, "Villages") 

    Dim cb As New OleDb.OleDbCommandBuilder(da) 

    dsNewRow = ds.Tables("Villages").NewRow() 

    dsNewRow.Item("ID") = numVils + 1 
    dsNewRow.Item("NameV") = playerName & "'s Village" 
    dsNewRow.Item("Xpos") = xpos 
    dsNewRow.Item("Ypos") = xpos 
    dsNewRow.Item("Owner") = playerID 


    ds.Tables("Villages").Rows.Add(dsNewRow) 

    da.Update(ds, "Villages") 

End Sub 

このサブルーチンに渡されたplayerIDは、私が作成したばかりのプレイヤーに関連付けられた正しい値ではありません(そのプレイヤーIDは常にplayerID = 1となるため、オートナンバーは、削除された行が削除されたために発生します。

プレーヤテーブルからIDの真の値を取得するにはどうすればよいですか?更新するオートナンバーを確認してから再チェックすることができますか?

+0

可能な複製を@ @IDENTITY WHERE in Access](http://stackoverflow.com/question) s/34269518/select-identity-where-in-access) – topshot

+0

IDなしで新しいプレーヤーを挿入します。次に、新しいIDが何であるかを調べます。次に、このIDでNewVillageを呼び出します。 – topshot

答えて

1

私が過去に行ったことは、OleDbDataAdapterのRowUpdatedイベントをフックし、そのフックでID検索コマンドを実行することでした。

まず、モジュールレベルでアイデンティティ句を実行し、それをインスタンス化する方法を追加するために使用されるコマンドを定義します。

Private cmdGetIdentity As OleDb.OleDbCommand 

Private Sub CreateIdentityCommand(con As OleDbConnection, tblName As String) 

    Dim sql As String = "SELECT @@IDENTITY FROM " & tblName 
    cmdGetIdentity = New OleDb.OleDbCommand(sql, con) 

End Sub 

次に、取得するために使用されるイベントハンドラを作成しますアイデンティティ(各テーブルにはID列が含まれているため、このコードは、あなたのテーブルの両方に使用することができます):

Private Sub RowUpdated(ByVal sender As Object, ByVal e As OleDbRowUpdatedEventArgs) 

    If e.Status = UpdateStatus.Continue AndAlso e.StatementType = StatementType.Insert Then 
     ' Execute the command and move it into the row 
     e.Row("ID") = Int32.Parse(cmdGetIdentity.ExecuteScalar().ToString()) 
     ' Ensure the row's changes are accepted 
     e.Row.AcceptChanges() 
    End If 

End Sub 

最後に、identityコマンドをインスタンス化し、新たなイベントをフックし、既存のを削除するために、既存の方法を変更しますIDを設定しようとするコード。

da = New OleDb.OleDbDataAdapter(Sql, con) 

da = New OleDb.OleDbDataAdapter(Sql, con) 
    CreateIdentityCommand(con, "Villages") 
    AddHandler da.RowUpdated, AddressOf RowUpdated 

にして、行削除:NewVillageでは、例えば、変更

 Dim numVils As Integer = getVilCount() 

と:[選択の

 dsNewRow.Item("ID") = numVils + 1 
+0

助けてくれてありがとう。これはまだ私の他のデータベースで間違ったインデックスを使用します(基本的に私は村を作って、村のテーブルの選手のユニークIDを使用してその村をプレイヤーに割り当てるプレイヤーを作成した後)。何らかの理由でコードを使用して最後の行の最初の位置(村の作成者に渡す)の値をチェックして間違った値を渡しているようです。それは、私が村を作った後のIDの更新のようなものです - プレーヤーを作るたびに強制的にこれが起こるように強制していますか? – FraserOfSmeg

関連する問題