| 「アップサイジングウィザード」に代わるプログラムの5回目です。
 今回は、Accessデータベース内からアップサイズ対象とするクエリ情報を収集して、SQL Server上に各種のオブジェクトを生成してみます。
 
 
 
 
         クエリ一覧の取得と種類による選別 
まず、Accessデータベース内にあるクエリの一覧を取得します。
 データベースの「QueryDefs」コレクションから「QueryDef」オブジェクトを取得することで、1つずつのクエリの定義を取り出します。
 さらに、QueryDefの「Name」プロパティで”クエリ名”を、「Type」プロパティで”クエリの種類”を、また「Parameters」コレクションの「Count」プロパティで”パラメータの数”を取得します。
 
 次のプログラムでは最初のステップとしてその結果をイミディエイトウィンドウに出力するだけですが、最終的にはSQL Server上に各種のオブジェクトを生成するものとして、それに関連した分岐処理やプロパティ取得を行っています。
 
 Sub TrySample_5_1()
 
 Dim dbs As Database
 Dim qdf As QueryDef
 
 Set dbs = CurrentDb
 For Each qdf In dbs.QueryDefs
 With qdf
 If Left$(.Name, 4) <> "~sq_" Then
 Debug.Print .Name,
 Select Case .Type
 Case dbQSelect
 Debug.Print "選択クエリ",
 If .Parameters.Count = 0 Then
 Debug.Print "パラメータなし"
 Else
 Debug.Print "パラメータあり"
 End If
 Case dbQAppend
 Debug.Print "追加クエリ"
 Case dbQUpdate
 Debug.Print "更新クエリ"
 Case dbQDelete
 Debug.Print "削除クエリ"
 Case Else
 Debug.Print "その他"
 End Select
 End If
 End With
 Next qdf
 
 End Sub
 
 
 
 
 
 CREATE文の生成と発行 
上記のプログラムを展開して、クエリの種類に応じて実際にSQL Severに「CREATE」文を発行し、各オブジェクトを生成します。
 
 ここで生成するCREATE文は次の3種類です。
 
          ビューの生成CREATE VIEW 
          ストアドファンクションの生成CREATE FUNCTION 
          ストアドプロシージャの生成CREATE PROCEDURE 
         
          パラメータがない選択クエリは『ビュー』として生成します。
パラメータがある選択クエリは『ストアドファンクション』(テーブル値関数)として生成します。ストアドプロシージャでもよいのですが、Accessのクエリと同様に「SELECT * FROM クエリ名」のように使えるよう、ここではストアドファンクションとします。
 ※最後にカッコを付けて「SELECT * FROM ストアドファンクション名()」のように使えます。
追加/更新/削除のいわゆるアクションクエリは『ストアドプロシージャ』として生成します。 
          その他の種類のクエリについては今回は考えないものとします。 
         CREATE文の組み立てにおいては、QueryDefオブジェクトの「SQL」プロパティを参照、それによってクエリのSQL文を取得・加工することでSQL Serverの文法に対応したSQL文を生成します。
 
 その実際のプログラム例が下記のものとなります。
 
 Sub TrySample_5_2()
 
 Dim dbsServer As Database
 Dim dbsLocal As Database
 Dim strConStr As String
 Dim qdf As QueryDef
 Dim strQdfSQL As String
 Dim strSQL As String
 Dim strPrmName As String
 Dim strPrmType 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 qdf In dbsLocal.QueryDefs
 strSQL = ""
 With qdf
 If Left$(.Name, 4) <> "~sq_" Then
 'SQLプロパティを取得(最後の;を除去)
 strQdfSQL = Replace(.SQL, ";", "")
 
 'AccessとSQL Serverの文法の違いを変換
 strQdfSQL = Replace(strQdfSQL, "&", "+")
 strQdfSQL = Replace(strQdfSQL, """", "'")
 strQdfSQL = Replace(strQdfSQL, "True", "1")
 strQdfSQL = Replace(strQdfSQL, "False", "0")
 
 'ORDER BY句があるときはTOP句を追加
 If InStr(strQdfSQL, "ORDER BY") > 0 And InStr(strQdfSQL, " TOP ") = 0 Then
 strQdfSQL = Replace(strQdfSQL, "SELECT ", "SELECT TOP (100) PERCENT ")
 End If
 
 'クエリの種類による分岐
 Select Case .Type
 Case dbQSelect
 If .Parameters.Count = 0 Then
 '選択クエリ(パラメータなし)
 strSQL = "CREATE VIEW " & .Name & " AS " & strQdfSQL
 
 Else
 '選択クエリ(パラメータあり)
 strPrmName = "@" & Replace(Replace(.Parameters(0).Name, "[", ""), "]", "")
 Select Case .Parameters(0).Type
 Case dbText: strPrmType = "nvarchar(255)"
 Case dbByte: strPrmType = "tinyint"
 Case dbInteger: strPrmType = "smallint"
 Case dbLong: strPrmType = "int"
 Case dbSingle: strPrmType = "real"
 Case dbDouble: strPrmType = "float"
 Case dbDate: strPrmType = "datetime"
 Case dbCurrency: strPrmType = "money"
 Case dbBoolean: strPrmType = "bit"
 End Select
 strQdfSQL = Replace(strQdfSQL, .Parameters(0).Name, strPrmName)
 strSQL = "CREATE FUNCTION " & .Name & _
 " (" & strPrmName & " " & strPrmType & ") " & _
 "RETURNS TABLE AS " & _
 "RETURN (" & strQdfSQL & ")"
 
 End If
 
 Case dbQAppend, dbQUpdate
 '追加/更新クエリ
 strSQL = "CREATE PROCEDURE " & .Name & " AS " & _
 "BEGIN " & strQdfSQL & " END"
 
 Case dbQDelete
 '削除クエリ
 strQdfSQL = "DELETE " & Mid(strQdfSQL, InStr(strQdfSQL, "FROM"))
 strSQL = "CREATE PROCEDURE " & .Name & " AS " & _
 "BEGIN " & strQdfSQL & " END"
 
 End Select
 End If
 End With
 
 If strSQL <> "" Then
 'SQL文をSQL Serverに発行
 dbsServer.Execute strSQL, dbSQLPassThrough
 End If
 
 Next qdf
 
 Exit_Here:
 Exit Sub
 
 Err_Handler:
 MsgBox "エラー番号:" & Err.Number & vbCrLf & vbCrLf & _
 "エラー内容:" & Err.Description, vbOKOnly + vbCritical
 Resume Exit_Here:
 
 End Sub
 
 
 
          AccessからCREATE文を発行する際、それがSQL Server上の単純な文法エラーであってもプログラムのエラーが発生します(dbsServer.Execute strSQLの行)。したがって、AccessとSQL
          Serverの文法上の相違点として考えられる箇所はすべて置き換えておく必要があります(今回はほんの少量のクエリの例に対応しただけです)。 
          ビューやストアドファンクションにおいてはORDER BY句だけではエラーとなります。そのため事前に「TOP (100) PERCENT」を追加しています。
          
          選択クエリ(パラメータあり)では複数のパラメータを考慮すべきですが、今回は”1ケのみ”という前提としています。また、一部のデータ型に限定、テキスト型は長さ255に固定としていますので、あまり汎用性のあるコードにはなっていません。
          
          削除クエリについては、Access側では「DELETE テーブル名.* FROM 〜〜〜」のような構文となりますが、SQL
          Server用には「DELETE FROM 〜〜〜」のような構文になるようにしています。 
         ストアドプロシージャ等に関しては、とりあえずできたとしてもいろいろSQL Server側でテストや編集が必要となるかもしれません。またストアドプロシージャのメリットでもあるのですが、Accessで複数のアクションクエリを連続して実行する場合、それらは別々のクエリとして作り1つずつ実行していく必要がありますが、ストアドプロシージャであれば1つのプロシージャ内にそれらをまとめて記述することもできます。他にもそのようなケースは多々ありますので、オブジェクト移行後もSQL
        Serverならでは機能を活かした改良が必要かもしれません。
 また上記はとりあえず出力するだけで、SQLのエディタで見たときのスクリプトの見栄えは考慮されていません。改行やインデントなども出力するプログラム側で実装するか、あるいはSQL
        Server上にできたものをきれいに整形した方がよいでようです。
 
 
 実行結果の例:
 
   
  
  
 
 
 ※クロス集計クエリの”qxrs売上”、テーブル作成クエリの”qmak商品マスタ”は除外されています。
 
 ■生成されたビューの例
 
  
 ■生成されたストアドプロシージャの例
 
   |