前々回、前回の記事でMariaDBからOracleやSQL Serverのデータを取得するため、unixODBCとCONNECTストレージエンジンを使って環境を構築した。
一部動作が怪しい所はあるものの概ね問題なく動いているのだが、一つ困ったこととして「エラーメッセージが文字化けする」という問題がある。
エラーメッセージ文字化け問題(Oracle編)
Oracleのビューに対してCONNECTでCREATE TABLEし、そのテーブルに対して編集しようとした(つまりビューを編集しようとした)らこのようなエラーメッセージが出た。
#HY000Got error 122 'Remote SQLExecDirect: [Oracle][ODBC][Ora]ORA-01732: ã\0081"ã\0081®ãƒ"ューã\0081§ã\0081¯ãƒ‡ãƒ¼ã‚¿æ"\008D作ã\0081Œç„¡åŠ¹ã\0081§ã\0081™
ヘルãƒ--: https://docs.orac' from CONNECT
↑ビューは編集できないのは分かるし、ORA-xxxxxの番号があるのでWeb検索すればエラー内容は理解できるんだけど、見事に文字化けしてる...。
まず調べてみた所、OracleのエラーメッセージはNLS_LANGに依存するとのこと。
確かに前々回の記事でSQL取得結果(日本語文字列)が「?」に文字化けしてしまうことから、環境変数に下記を設定した。
NLS_LANG=JAPANESE_JAPAN.JA16SJISTILDE
これによりエラーメッセージも日本語で表示されるようになったわけだ。
そこまではいいのだが、肝心の文字化けしてしまう原因については、どうやらUnixODBCがコード変換時に誤ってISO-8859-1でエンコードしてしまっているらしい。うーんポンコツ。困った。
前回の記事ではMariaDBから同一ネットワーク上にあるOracleにCONNECTストレージエンジンを使って接続してみた。
今回はその続きで、MariaDBからSQL Serverにリンクしてみた。
参考記事
今回はこちらの記事を参考にした。
【MySQL】MariaDB使用connect引擎直接访问SQLServer数据库 - abce - 博客园
使用するODBC Driver for SQL Serverのバージョンが違うことを除けば、ほぼこの手順のとおりで完了する。
その他の細かい設定などは前の記事で実施済みなので割愛する。
この記事の続き。手こずっているシステムのバグ対応でまた躓いた。
Entity Frameworkなんて使ったことねぇよ。わかんねー
事の発端
とある画面を表示する際、初期表示データを取得するためのDBアクセス時にEntity Frameworkが例外エラーを吐くことがある。
A second operation was started on this context before a previous operation completed. This is usually caused by different threads concurrently using the same instance of DbContext. For more information on how to avoid threading issues with DbContext, see https://go.microsoft.com/fwlink/?linkid=2097913.
at Microsoft.EntityFrameworkCore.Internal.ConcurrencyDetector.EnterCriticalSection()
at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()
at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.SingleAsync[TSource](IAsyncEnumerable`1 asyncEnumerable, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.SingleAsync[TSource](IAsyncEnumerable`1 asyncEnumerable, CancellationToken cancellationToken)
at NameSpace.DataAccess.CustomerMasterAccess.GetItem(String customerCode) in C:\*****.cs:line 74
at NameSpace.DataAccess.MasterAccess.GetCustomerName(String customerCode) in C:\*****.cs:line 125
at NameSpace.Forms.DataInput.SetCustomerName(String customerCode, String customerCode2, String customerCode3) in C:\*****.cs:line 475
at NameSpace.Forms.DataInput.DisplayItems() in C:\*****.cs:line 90
at NameSpace.Forms.DataInput.Initial() in C:\*****.cs:line 71
at System.Threading.Tasks.Task.<>c.<ThrowAsync>b__140_0(Object state)
"A second operation started on this context before a previous operation completed"というエラーメッセージでググってみると、「DbContext はスレッドセーフではないので、スレッド間で使いまわしてはいけない」という文言が見つかる。
つまりこのエラーは複数スレッドから同じDbContextにアクセスしてしまったため発生しているようだ(エラーメッセージに書いている通りやね)
事の発端
- SQL Server 2000から2016へのリプレース作業中
- 客から「新システムに入力した一部データを旧システムに戻したい」という要望
- SQL Server 2016から一部のデータを取り出してSQL Server 2000に入れることに
旧から新にデータ移行したことはあったけど、新から旧ってなかなかなくない...?
まぁ今回はそれに関係なく「SQL Serverのデータ移行がクソ面倒だった」というお話だけど。