トップ回答者
[VB6.0]ファイル読込みモジュールを作りたいのですが・・・

質問
-
こんばんは。 VB6.0初心者です。
VB6.0でのSQL文の記述方法でご教授いただきたく思います。
下記のようなSQL文を多数記述したファイル(仮に AAA.SQL)を、VBプロジェクト等と同じフォルダ内に保存し
プログラム内から指定したSQL文だけを取り込みたく考えています。
ex)
SQL_001_SELECT を指定
↓
SELECT
FIELD_A,
FIELD_B,
FIELD_C
FROM
MASTER
WHERE
KEY = #KEY#
が取り込まれる
↓
#~# をプログラム内で置き換え
↓
SQL文完成
ソース内にSQL文を直接記述する方法もありますが、できればSQl文を別に記述したく思っているので、
解決方法や手法等ご存知の方がいらっしゃればご教授お願いします。
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[SQL_001_SELECT]
SELECT
FIELD_A,
FIELD_B,
FIELD_C
FROM
MASTER
WHERE
KEY = #KEY#
[SQL_002_SELCT]
SELECT
FIELD_A
FIELD_B
FIELD_C
FROM
JOURNAL
[SQL_001_UPDATE]
UPDATE
MASTER
SET
FIELD_A = '#FIELD_A#'
FIELD_B = '#FIELD_B#'
FIELD_C = '#FIELD_C#'
WHERE
KEY = #KEY#
回答
すべての返信
-
InStr 関数で、"#"の位置がわかります。
Mid ステートメントで、文字を置き換えることができます。
Mid 関数で、文字を取得することができます。その1
LoopとInStr 関数で全ての"#"の始点と終点を配列に取ります。
数が合わないときは、エラーにします。下記が配列のイメージです。
始点 終点 記号
10 15
30 35次に、配列の最初より、LoopとMid 関数で
記号を取得します。(上記と同時に取得しても良い)
下記が配列のイメージです。始点 終点 記号
10 15 KEY
30 35 KEY次に、配列の最初より、LoopとMid ステートメントで
記号を条件判断した後、文字を置き換えます。その2
LoopとInStr 関数で"#"を基に文字列をバラバラにして、
配列にしまいます。
下記が配列のイメージです。文字配列
UPDATE MASTER SET FIELD_A = '
#FIELD_A#
' FIELD_B = '
#FIELD_B#
' FIELD_C = '
#FIELD_C#
' WHERE KEY =
#KEY#改行やスペースは、そのまま配列に入れますが、表記の都合で省略しました。
"#"で始まる要素を条件判断した後、文字を置き換えます。
そのほかにも色々な方法があると思います。
記号を条件判断する場合、大文字に変換してから比較するなどすれば、
記述間違いなどに、耐性を持ちます。
(反面バグの原因にもなります。)"#"が、本文に出てこないことが、条件です。
汎用性を問わないので、それでよいと思います。ところで、"UPDATE MASTER SET FIELD_A ="の文は、
カンマが抜けているので、エラーになります。趣旨は、よくわかるのですが、
実際のところ、お勧めしません。
SQL文を記述するのではなく、「作る」ような、方法にはならないのでしょうか。 -
かさこ さんからの引用 ソース内にSQL文を直接記述する方法もありますが、できればSQl文を別に記述したく思っているので、
解決方法や手法等ご存知の方がいらっしゃればご教授お願いします。
ソース内にクエリーを直接記述しないのはいい考えだと思います。
かさこさんは、「ファイルに保存」と書かれていますが、ストアドプロシージャを使ってみてはどうでしょうか?
VB6ということなのでADOを使ってデータベースとアクセスすると思いますが、扱いとしては通常のクエリーとほとんど変わりませんし、クエリーの修正された場合でも、ストアドプロシージャの修正のみでソースコードの修正は不要です。
※ただし、パラメータが追加された場合は別ですが。
もし必要があればサンプルコードを示しますので、その場合は返信してください。
-
CatTail 様
おはようございます。
以前(1年半程前)にC#2005(DB:SQLサーバ2005)でプログラミングした経験があるのですがVB6.0は未経験なため、
.NET2005ではできてVB6.0ではできない部分があり、少し困惑しております。
手元にある既存システムのプログラムでは、ソース内に"&"でつなぎ合わせてSQL文を作っていますが、見直すと非常に
読みにくく感じます。(特にINSERT文)
そこで、C#2005プログラミング時にしていた"ソース"と"SQL文"を分ける方法を利用したく考えています。
(この方法でも、SQL文だけの変更時はソース変更不要)
CatTail様が言われている「ストアドプロシージャ」を利用するのも良いことかもしれませんが、VB6.0初心者・ストアド初心者
なため何から手をつければいいのか・・・って状態です。
初心者なのに「したい事」だけはイッチョマエで申し訳ありません。
ソースのサンプル、ストアドプロシージャのサンプル等が記載されているページをお知りであれば、お教えいただきたく
思います。
環境
PC:ウインドウズXP Pro
開発ツール:VisualStadio6.0 SP6(VB)
DB:SQLサーバ2005
-
かさこ さんからの引用 CatTail様が言われている「ストアドプロシージャ」を利用するのも良いことかもしれませんが、VB6.0初心者・ストアド初心者
なため何から手をつければいいのか・・・って状態です。
とりあえず、パラメータ クエリを使用してみましょう。
SQL Server 2000 自習書シリーズ開発編 No.3 (30頁あたり)http://download.microsoft.com/download/8/4/9/84988d60-4f3b-4286-bc19-817a32050c6d/SQL2000DEV-03.doc
ADO を使用して Access データベースへのパラメータ クエリを呼び出す方法
その上でストアド プロシージャに関して調べてみるとよいと思います。
ADO で SQL Server のストアド プロシージャの値を取得する方法
Append、CreateParameter メソッドの例 (VB)
まずデータベースに対してストアドプロシージャを作成します。
SQL Server 2005以降であれば、SQL Server Management Studioで[新しいクエリ]をクリックします。
注意点として、ストアドプロシージャはデータベースに対して作成されるので、対象となるデータベースを切り替えます。
---- ここから ----
CREATE PROCEDURE SQL_001_SELECT
(
@p1 INT = NULL,
@p2 INT = NULL
)
SET NOCOUNT ON
DECLARE @query nvarchar(max)
SET @query = N'SELECT FIELD_A, FIELD_B, FIELD_C FROM MASTER'
IF @p1 IS NOT NULL BEGIN
-- 抽出条件の指定
END
- 中略 -
exec sp_executesql @stmt = @query, @params = 'パラメータの型指定', @param1 = 'パラメータ値'
---- ここまで ----
※EXECUTE(@query)でも生成したクエリーを実行できますが、SQLインジェクション攻撃の対象となるので、sp_executesqlを使ってください。
ストアドプロシージャを作成するクエリーを作成したら実行します。
文法エラーなどがなければ、[プログラミング]-[ストアドプロシージャ]に登録されます。
次にVBからの呼び出し方法です。
RecordsetにSELECTクエリーの代わりにストアドプロシージャを指定するだけです。
例)
SET rst = ".dbo.SQL_001_SELECT @p1 = 1"
rst.Open
Do While rst.Eof = False
' 何らかの処理
Loop
細かく説明すると長くなりすぎるため、大雑把な説明で分かりにくいかもしれません。
わからない部分を指摘してもらえれば詳細を説明しますので、よろしくお願いします。
txtファイルから取込む手法。
Dim fileNum As Long
Dim sql As String
Dim buffSql As String
Dim firstLine As Boolean
firstLine = True
fileNum = FreeFile
Open "d:\aaa.txt" For Input As #fileNum
Do Until EOF(fileNum)
Line Input #fileNum, buffSql
If firstLine Then
sql = buffSql
firstLine = False
Else
sql = sql & vbCrLf & buffSql
End If
Loop
Close #fileNum
一度に読み込む方法は、あったような、なかったような。。。
方針を決めておられるようですからおせっかいですけれども、
いくつかの関数を作って、整理すれば、そんなに見づらくもないと思います。
また、ストアドも、とても有効な手段だと思います。
例
Private Sub InsertSql()
sql = sql & "INSERT INTO tbl1 (val_num1,val_str2,val_num3) VALUES ("
sql = sql & ToSqlNum(Text1.Text)
sql = sql & ","
sql = sql & ToSqlStr(Text2.Text)
sql = sql & ","
sql = sql & ToSqlNum(Text3.Text)
sql = sql & ")"
...............
End Sub
Private Function ToSqlNum(val As String) As String
If val = "" Then
ToSqlNum = "NULL"
Else
ToSqlNum = val
End If
End Function
Private Function ToSqlStr(val As String) As String
If val = "" Then
ToSqlNum = "NULL"
Else
ToSqlNum = "'" & val & "'"
End If
End Function
karashima 様
こんばんは。
VB6.0 SP6 でのプログラミングです。。。
理想としては・・・
'SQL文取込
strSQL = SQL_UPTAKE("SQL_001_UPDATE")
'文字列置換strSQL = replace(strSQL, '#FIELD_A#', strFIELD_A)
strSQL = replace(strSQL, '#FIELD_B#', strFIELD_B)
strSQL = replace(strSQL, '#FIELD_C#', strFIELD_C)
strSQL = replace(strSQL, #KEY#, iKEY)
のようにイメージしています。
SQL文取込部分の関数ができれば、ソースに直接SQL文を記載することがなくなるので、SQL文を記述している部分は見やすいソースになると思うんです。
※スレッド内のSQL文のカンマが記入漏れしてるのは気にしないで下さい
指定したファイルから指定したキーワードの文字列を取得するって事で、以下のようなコードでどうですか?
# テストしていないんで、バグがあったらごめんなさい。
Private Sub foo()
Dim query As String
query = GetSqlQuery("[SQL_001_SELECT]", "AAA.SQL")
' 対象となるキーが見つからなかった
If query = "" Then
Exit Sub
End If
' 検索条件などの置き換え処理
End Sub
' 指定したファイルから特定のキーワードのSQLクエリーを取得する
Private Function GetSqlQuery(Keyword As String, Filename As strng) As String
Dim n As Integer
n = FreeFile()
Open Filename For Input As #n
' Keywordで指定された文字列まで読み込み
Dim dummy_data As String
Do While EOF(n)
' 1行読み込んで、キーと一致したらループから抜ける
Line Input #n, dummy_data
If dummy_data = Keyword Then
Exit Do
End If
Loop
' EOFだったら対象となるキーが存在しない
If EOF(n) = True Then
GetSqlQuery = ""
Exit Function
End If
Dim query_data As String
Dim query As String
query = ""
Do While EOF(n)
' 1行読み込んで、"["で始まっていたらループから抜ける
Line Input #n, query_data
If Left$(query_data, 1) = "[" Then
Exit Do
End If
query = query + query_data
Loop
GetSqlQuery = query
Close #n
End Function
# でもストアドプロシージャ方が楽だと思うけど…。
こんばんは。
下記のコードで指定したSQL文を正常に取込めるのを確認しました。
何度もご教授いただきありがとうございました。
' 指定したファイルから特定のキーワードのSQLクエリーを取得する
Private Function GetSqlQuery(Keyword As String, Filename As Strng) As String
Dim n As Integer
'n = FreeFile()
n = FileSystem.FreeFile()
Open FileName For Input As #n
Call MsgBox("ファイル=" & FileName)
' Keywordで指定された文字列まで読み込み
Dim dummy_data As String
'Do While EOF(n)
Do While (Not FileSystem.EOF(n))
' 1行読み込んで、キーと一致したらループから抜ける
Line Input #n, dummy_data
If dummy_data = Keyword Then
Exit Do
End If
Loop
Call MsgBox("キーワード=" & Keyword & "," & "データ=" & dummy_data & "," & "n=" & n)
' EOFだったら対象となるキーが存在しない
If EOF(n) = True Then
GetSqlQuery = ""
Exit Function
End If
Dim query_data As String
Dim Query As String
Query = ""
'Do While EOF(n)
Do While (Not FileSystem.EOF(n))
' 1行読み込んで、"["で始まっていたらループから抜ける
Line Input #n, query_data
If Left$(query_data, 1) = "[" Then
Exit Do
End If
Query = Query + query_data + vbNewLine
Loop
GetSqlQuery = Query
Close #n
End Function