■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