DOBON.NETプログラミング道掲示板

No35091 の記事


■35091 / )  Re[1]: CommandBuilderによって作られるCommandTextの内容
□投稿者/ 魔界の仮面弁士 大御所(1431回)-(2022/06/28(Tue) 20:51:37)
  • アイコン
    No35088に返信(Wanさんの記事)
    > 'UPD_ Cmd.CommandText :UPDATE 既存テーブル SET 苗字 = ?, 名前 = ?, 年齢 = ? 
    > WHERE ((ID = ?) AND 
    > ((? = 1 AND 苗字 IS NULL) OR (苗字 = ?)) AND 
    > ((? = 1 AND 名前 IS NULL) OR (名前 = ?)) AND 
    > ((? = 1 AND 年齢 IS NULL) OR (年齢 = ?)))
    
    No35089 の機能は、SourceColumnNullMapping プロパティによって制御されています。
    
    Dim sb As New System.Text.StringBuilder()
    sb.AppendLine($"UpdateCommand のパラメータ数={UPD_Cmd.Parameters.Count}")
    For Each p As OleDbParameter In UPD_Cmd.Parameters
        sb.Append($"{p.ParameterName,-4}{vbTab}")
        sb.Append($"{p.SourceVersion,-8}{vbTab}")
        sb.Append($"{If(p.SourceColumnNullMapping, "T", "F")}{vbTab}")
        sb.Append($"{p.OleDbType,-8}{vbTab}")
        sb.AppendLine($"{p.SourceColumn}")
    Next
    Debug.WriteLine(sb.ToString())
    
    上記を実行すると、このような表が得られます。
    p1,p5,p6 の違いに着目してみてください。
    
    ================================================
    UpdateCommand のパラメータ数=10
    p1    Current    F   VarWChar  苗字
    p2    Current    F   VarWChar  名前
    p3    Current    F   Numeric   年齢
    p4    Original   F   Integer   ID
    p5    Original   T   Integer   苗字
    p6    Original   F   VarWChar  苗字
    p7    Original   T   Integer   名前
    p8    Original   F   VarWChar  名前
    p9    Original   T   Integer   年齢
    p10   Original   F   Numeric   年齢
    ================================================
    
    Original は SELECT した時点の元の値を意味し、
    Current は、これから反映させたい編集後の値です。
    
    「p5 と p6」「p7 と p8」「p9 と p10」では、
    SourceColumn は同じですが、
    SourceColumnNullMapping が異なっていますよね。これが
     (? = 1 AND {SourceColumn} IS NULL) OR ({SourceColumn} = ?)
    の正体となります。
    
    
    --- 以下蛇足 ---
    > インスタンス名	Access2010
    Access 2010 世代のプロバイダー名は、本来は
    "Microsoft.ACE.OLEDB.12.0" ですね。もちろん
    "Microsoft.ACE.OLEDB.16.0" からでもアクセス可能ですが。
    
    
    > Dim oledb As String = "Microsoft.ACE.OLEDB.16.0;"
    oledb という変数名を付けて後で、それと同名の
    > Dim Cn As New OleDb.OleDbConnection(…
    な OleDb 名前空間を記述されていますね。
    名前が被って分かりにくくなりませんか?
    
    それ以外の
    > Dim Da As New OleDbDataAdapter(…
    > Dim builder As OleDbCommandBuilder = …
    では、OleDb. が無い状態にそろえてあるのに対し、
    oledb 変数名が必要なところだけが意図的に
    OleDb. 付きの表記なので、ちょっと混乱しそうです。
    もちろん、文法的には問題ないのですけれども。
    
    
    > Dim Cn As New OleDb.OleDbConnection($"Provider={oledb} Data Source={acfile}")
    プロバイダー名にセミコロンを入れるのは不自然ですね。
     Dim oledb As String = "Microsoft.ACE.OLEDB.16.0;"
     $"Provider={oledb} Data Source={acfile}"
    よりは
     Dim oledb As String = "Microsoft.ACE.OLEDB.16.0"
     $"Provider={oledb};Data Source={acfile}"
    の方が好ましいですよ。他のパラメーターもセミコロン区切りなので。
    
    実際のところ、接続文字列は
     Dim csb As New OleDbConnectionStringBuilder()
     csb.Provider = "Microsoft.ACE.OLEDB.16.0"
     csb.DataSource = "D:\データベース勉強用DB\INSERT文.accdb"
     Dim Cn As New OleDbConnection(csb.ConnectionString)
    のようにして組み立てることもできるのですが、この際に
     csb.Provider = "Microsoft.ACE.OLEDB.16.0;"
    としてしまうと、正しく接続できなくなります。
    
    
    > Dim Da As New OleDbDataAdapter("SELECT * FROM 既存テーブル", Cn)
    [既存テーブル] なのですね。冒頭の記述から [Test] かと誤解してました。
    
    > (Accessのテーブル構成)
    > インスタンス名	Access2010
    > データベース名	データベース勉強用DB
    > 論理テーブル名	Test
    > 物理テーブル名	INSERT文.accdb

違反を報告
返信 削除キー/


Mode/  Pass/


- Child Tree -