#59 SQL Serverアップサイズトライアル(4)

「アップサイジングウィザード」に代わるプログラムの4回目です。
テーブルのSQL Serverへの移行ができたので、それに関連してAccess側のリレーションシップをSQL Serverへも適用してみます。


リレーションシップ情報の取得

まずAccessのデータベース上で設定されているリレーションシップの情報収集を行います。それには次のようなプログラムを使います。

Sub TrySample_4_1()

  Dim dbs As Database
  Dim rel As Relation

  Set dbs = CurrentDb
  For Each rel In dbs.Relations
    If Not (rel.Attributes And dbRelationInherited) And _
        (Left$(rel.Table, 4) <> "MSys" And Left$(rel.ForeignTable, 4) <> "MSys") Then
      'リンクテーブルとシステムテーブルのリレーションシップは除外
      With rel
        Debug.Print .Name                                           'リレーションシップ名
        Debug.Print .Table                                          '主側テーブル名
        Debug.Print .ForeignTable                                   '外部テーブル名
        Debug.Print .Fields(0).Name                                 '主側結合フィールド名
        Debug.Print .Fields(0).ForeignName                          '外部結合フィールド名
        Debug.Print (.Attributes And dbRelationUpdateCascade) > 0   '連鎖更新
        Debug.Print (.Attributes And dbRelationDeleteCascade) > 0   '連鎖削除
      End With
    End If
  Next rel

End Sub

カレントデータベースのリレーションシップ全体である「Relations」コレクションをループで辿り、そこから1つずつ「Relation」オブジェクトを取り出していきます。
1つのRelationオブジェクトがリレーションシップの画面における結合線1つを表しています。よってそのオブジェクトの所定のプロパティを参照することで、リレーションシップの結合の内容を調べることができます。
ここでは、次のステップでのSQL ServerへのSQL文の発行に必要となる6つのプロパティを参照し、イミディエイトウィンドウに出力しています。



リレーションシップのSQL文の生成と発行

Access側のリレーションシップの情報を収集したら、その1つ1つについて、「ALTER TABLE」のSQL文を組み立ててSQL Serverへ発行します。
その際のSQLの構文は次のようなものです。それぞれについて上記でコードで取得したプロパティ値を当てはめていきます。

ALTER TABLE テーブル名
ADD CONSTRAINT リレーションシップ名
FOREIGN KEY (フィールド名)
REFERENCES 参照先テーブル名 (参照先フィールド名)
ON UPDATE CASCADE
ON DELETE CASCADE

  • 「ON UPDATE CASCADE」は「連鎖更新」を設定することを表します。
  • 「ON DELETE CASCADE」は「連鎖削除」を設定することを表します。

実際にその一連の処理を行うプログラムが次のコードになります。
  • リレーションシップ名は一意であればかまいませんので、Access側のプロパティ値をそのまま使えます。ただし今回のプログラムでは「FK_テーブル名_参照先テーブル名」という構成の名前を付けるものとしました。
  • Access側のRelationオブジェクトを調べると、2つのテーブルが「1対多」の関係にあるとき、1側が”主側テーブル”、多側が”外部テーブル”として取得されます。そのまま主側を”テーブル名”、多側を”参照先テーブル”とするSQL文ではエラーとなりリレーションシップが生成されませんでした。そこで下記プログラムでは1側を”外部テーブル”のプロパティ値、多側を”主側テーブル”のプロパティ値に置き換えて実行しています。
  • このプロシージャではローカルのAccessデータベースとSQL Server上のデータベースの2つのDatabaseオブジェクトを扱っています。それぞれ「Dim dbsServer」、「dbsLocal」という2つの変数で使い分けています。

Sub TrySample_4_2()

  Dim dbsServer As Database
  Dim dbsLocal As Database
  Dim strConStr As String
  Dim rel As Relation
  Dim strSQL As String

  strConStr = "ODBC;DRIVER=SQL Server;" & _
              "SERVER=NAFUREI;" & _
              "DATABASE=UpSizeTest;" & _
              "Trusted_Connection=Yes;"

  On Error GoTo Err_Handler

  'SQL Server上のUpSizeTestデータベースに接続
  Set dbsServer = OpenDatabase("", False, False, strConStr)

  Set dbsLocal = CurrentDb
  For Each rel In dbsLocal.Relations
    With rel
      'リンクテーブルとシステムテーブルのリレーションシップは除外
      If Not (.Attributes And dbRelationInherited) And _
        (Left$(.Table, 4) <> "MSys" And Left$(.ForeignTable, 4) <> "MSys") Then
        'RelationオブジェクトのプロパティからSQL文を組み立て
        strSQL = "ALTER TABLE " & .ForeignTable & " " & _
                  "ADD CONSTRAINT " & "FK_" & .ForeignTable & "_" & .Table & " " & _
                  "FOREIGN KEY (" & .Fields(0).ForeignName & ") " & _
                  "REFERENCES " & .Table & " (" & .Fields(0).Name & ") "
        If (.Attributes And dbRelationUpdateCascade) > 0 Then
          strSQL = strSQL & "ON UPDATE CASCADE "
        End If
        If (.Attributes And dbRelationDeleteCascade) > 0 Then
          strSQL = strSQL & "ON DELETE CASCADE "
        End If

        'SQL文をSQL Serverに発行
        dbsServer.Execute strSQL, dbSQLPassThrough

      End If
    End With
  Next rel

Exit_Here:
  Exit Sub

Err_Handler:
  MsgBox "エラー番号:" & Err.Number & vbCrLf & vbCrLf & _
         "エラー内容:" & Err.Description, vbOKOnly + vbCritical
  Resume Exit_Here:

End Sub






| Index | Prev | Next |



Copyright © T'sWare All rights reserved