2020年1月6日月曜日

VB DB TableAdapter の ScalarQuery の件

単一の値を返す TableAdapter の ScalarQuery は自動生成されて、とても、便利です。
でも、自動生成は ... 。
思わぬ所に、落とし穴があったりして。
そう、もし、バックアップから復帰させた Table の構造が違っていたら ... 。


私、DataBase の列名で、設計設定時に、良く、スペルミスをしたりします。
知らぬまま、突っ走っていると、
ある日突然、それに気付き、別の変更と共に直す事もあったりします。
関連するコードの修正は、勿論、行います!。

今回は、こんな状況下での出来事です。
DataBase のうち、管理用に設けた Table の設計(構造 = 列名変更も含む )を変え、
主要な Table 群は弄らずに、あれこれ、キーボードを叩いていました。
そこで、直面したのが、
管理テーブルから引き出す、日付データが欠落する問題!。
現状のデータで問題は起こりませんが、
古いバックアップを引き摺り出した場合には ... 。
勿論、そこには、そんな名称の 列 は無いので、
取得しに行った途端に、エラーを吐いて、止まって仕舞います。
主要部分には手を付けていないので、
本来表示可能な部分が巻き添えを喰らって、ソフトそのものがダウンして仕舞いました。

  問題は、古いデータのバックアップからデータリストアした場合に起こります。
  古いデータでは、DataBase の構造も 古いまま だからです。

古いバックアップデータにも手を加えれば良いのですが ... 。
データを触らずに、何とかするぞぉ~、 と頑張った結果が これ!。

はい。
無論、管理テーブル を DataGridView で操作する部分等も、不都合が生じるので、
そこへジャンプしない様に、Control の Enable を切り替えて、阻止しています。

DB TableAdapter の ScalarQuery の自動生成されたコードを弄ります。
XXX_DataSet.Designer.vb が該当コードになります。
Debug で示される該当コード部分の箇所ですが、
もし、これを、ソースから見付けるとなると、その分量が巨大な為、辟易して仕舞います。.
Try 句に、Catch を噛ませ、値を入れてやります。
Nothing を返して仕舞うと、ToString() が受けた時に、エラーになるのでしたね ... (?) 。
面倒なので、1900 年と言う適当なものを選んだ訳です。

        Public Overloads Overridable Function LastModified_Query() As Object
            Dim command As Global.System.Data.SqlClient.SqlCommand = Me.CommandCollection(4)
            Dim previousConnectionState As Global.System.Data.ConnectionState = command.Connection.State
            If ((command.Connection.State And Global.System.Data.ConnectionState.Open)  _
                        <> Global.System.Data.ConnectionState.Open) Then
                command.Connection.Open
            End If
            Dim returnValue As Object
            Try
                returnValue = command.ExecuteScalar
   Catch ex As Exception
                returnValue = New DateTime(1900, 1, 1, 1, 1, 1)   'For Old DB Loading
            Finally
                If (previousConnectionState = Global.System.Data.ConnectionState.Closed) Then
                    command.Connection.Close
                End If
            End Try
            If ((returnValue Is Nothing)  _
                        OrElse (returnValue.GetType Is GetType(Global.System.DBNull))) Then
                Return Nothing
            Else
                Return CType(returnValue,Object)
            End If
        End Function


この方法の欠点は、
xsd ファイルを開いて、自動生成が働くと、元に戻されて仕舞う事!。
いたちごっこ ですね。
将来、この件を覚えているか知らん ... 。  X|

順当(適切)なのは、 やはり、
バックアップデータを開き、Table Drop そして 再生成 (或いは、構造変更)なのは予想が付きますが、
File System の TimeStamp も触る事になるので、面倒なのです。

  結果的には、後日、Visual Studio IDE 等 から、コツコツと、修正しましたが ... 。.

或いは、古い構造の異なる DataBase には触らない事! でしょうか?。



データベースは気軽に名称変更等をすると、 後で、とんでもない! 事態に遭遇します。
分かってはいるのですが、
ミススペルは ねぇ~ と言う訳でして ... 。
もっと、 柔軟 になってくれると良いのですが ... 。

        いいえ、 データベース設計には先を見越した充分な配慮を! と言う事でしょうか?。



0 件のコメント:

コメントを投稿