ODBC接続MySQLテーブルに更新クエリが競合エラー

ACCESS2016のサンプルデータベースNorthwind.accdbで実験
テーブルの社員をMySQLへエクスポート 名前はsyainに変更し ODBCでリンク
テスト用のプロシージャ作成

sub mytest()
Dim cn As ADODB.Connection
Dim cmd As ADODB.Command
Dim strSQL As String
strSQL = “UPDATE syain SET syain.氏名 = ‘おれおれ’ WHERE syain.社員コード=?”

Set cn = CurrentProject.Connection
Set cmd = New ADODB.Command
cmd.ActiveConnection = cn
cmd.CommandText = strSQL

cmd.Prepared=True
cmd.Execute , 110

cn.Close
Set rs = Nothing
Set cmd = Nothing
Set cn = Nothing

End Sub

パラメータ付き更新クエリの発行です。
1回目は成功 そして何もせず続けて2回目実行
2回目以降は実行時エラー-2147467259 他のユーザーが同じデータに対して同時に変更を試みているので、プロセスが停止しました
他のユーザーって誰もいませんけど?
こういう仕様なんだろうと試行錯誤して

Dim cn As ADODB.Connection
Dim cmd As ADODB.Command
Dim strSQL As String
Dim Param As Long
strSQL = “UPDATE syain SET syain.氏名 = ‘おれおれ’ WHERE syain.社員コード=” & Param
Param = 105

Set cn = CurrentProject.Connection
Set cmd = New ADODB.Command
cmd.ActiveConnection = cn
cmd.CommandText = strSQL

cmd.Prepared=True
cmd.Execute

cn.Close
Set rs = Nothing
Set cmd = Nothing
Set cn = Nothing

End Sub
とパラメータをsql文の外に出すと競合エラーが出ないことがわかりました。
なぜ最初の構文で競合エラーかずっとわからなかったのですが
VBAからの更新クエリの返事にMySQLがaffected rowsを
返すかららしい。

ODBCのオプション変更でも回避できるようです。こちらの方が簡単ですね。
Return matched rows instead of affected rows
https://ameblo.jp/blueskyame/entry-10247966762.html

しかしまだわからない点があって
Return matched rows instead of affected rows
で競合エラーは出なくなりますがクエリを発行するたびに新しいODBC接続になります。
パラメータsql文外コードでは接続は増えません。

accessのバージョンでも挙動が異なるし難しい
たぶんACEになってからでしょうか
2000では何も問題はなかった。
any_windowsOS_64bit access2016_32bit odbc5.3unicode mysql5.7.17

Dim — as New

以前より気になっていたけど

Dim rs as New ADODB.Recordset
Set rs = New ADODB.Recordset

と書いても問題ないし

Dim rs as ADODB.Recordset
Set rs = New ADODB.Recordset

と書いても問題ない、New ってなんだといろいろググってみました。
オブジェクト変数とは何ぞや、メモリーに領域を確保云々 とかは置いといて

宣言文にNewを入れるのはVB6とVBAでしか通用しないらしい
Dim rs as New ADODB.Recordset
一文で
Dim rs as ADODB.Recordset
Set rs = New ADODB.Recordset
のセット注文らしい
ということは最初の構文はラーメンセットとラーメンオーダーしてるようなもんですね

まあ普通は・・Stringを例にすれば
Dim Str as String
Str = “あいうえお”
の宣言してから、変数代入が由緒正しき作法でしょうから
今後は宣言に New ADODB.Recordset とかはやめよう

値渡しと参照渡し

こんにちは
値渡しと参照渡し
sub sample(Byval Str as string) とか sub sample(ByRef Str as string) とかいうやつです。
Google先生に聞けばその時はなるほどと分かったようなつもりだけど、説明せよと言われると??

自分も call *** は書きますがせいぜい条件分岐が長すぎてわかりやすくするためsubに分けたり 
public function sample(param as long) as boolean のようなパブリック関数呼び出しなので
値渡し、参照渡しは意識したことがなかった。

結局、値渡しは値を sub に渡すだけ
渡したら知らんぷり
参照渡しは引数として渡して一緒に使いましょう
ということなのか?

そういう風に覚えよう。

Byvalのvalはvalueでしょうね、持ってけ!ドロボー、返せと言っても返さんでいいからな!・・かな?
Byrefのrefはreferenceかな? 参照、紹介、参考とかいう意味だな。 これあげるね、でも必要な時は声かけるから返してね、ラッピングして・・かな?

ちなみにVBAの場合は書かなければByrefがデフォルトだそうな。