「アップサイジングウィザード」に代わるプログラムの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商品マスタ”は除外されています。
■生成されたビューの例
■生成されたストアドプロシージャの例
|