none
[VB6.0]ファイル読込みモジュールを作りたいのですが・・・ RRS feed

  • 質問

  • こんばんは。 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#

    2009年1月7日 10:42

回答

  • ごめんなさい。VB6のソースからコードスニペッドにコピペしたんですが、編集した際に文字を消してしまったみたいです。

    以下の部分を変更してください。

     

    Private Function GetSqlQuery(Keyword As String, Filename As strng) As String

    Private Function GetSqlQuery(Keyword As String, Filename As String) As String

    2009年1月19日 15:00

すべての返信

  •  

    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文を記述するのではなく、「作る」ような、方法にはならないのでしょうか。

    2009年1月7日 11:57
  •  かさこ さんからの引用

    ソース内にSQL文を直接記述する方法もありますが、できればSQl文を別に記述したく思っているので、

    解決方法や手法等ご存知の方がいらっしゃればご教授お願いします。

     

     ソース内にクエリーを直接記述しないのはいい考えだと思います。

     かさこさんは、「ファイルに保存」と書かれていますが、ストアドプロシージャを使ってみてはどうでしょうか?

     

     VB6ということなのでADOを使ってデータベースとアクセスすると思いますが、扱いとしては通常のクエリーとほとんど変わりませんし、クエリーの修正された場合でも、ストアドプロシージャの修正のみでソースコードの修正は不要です。

    ※ただし、パラメータが追加された場合は別ですが。

     

     もし必要があればサンプルコードを示しますので、その場合は返信してください。

     

     

    2009年1月7日 11:59
  •  かさこ さんからの引用

    下記のようなSQL文を多数記述したファイル(仮に AAA.SQL)を、VBプロジェクト等と同じフォルダ内に保存し

    プログラム内から指定したSQL文だけを取り込みたく考えています。

    簡単に書き換えられてしまう事を考えると怖いですね。
    クエリを取得する関数等を別dllにするという方法も考えられますが

    CatTail さんがおっしゃられている様にストアドにする方がよいでしょうね。

    2009年1月7日 16:10
  • 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

    2009年1月8日 2:05
  • こんにちは。

     

    UPDATE文のカンマは記載漏れです。

    SQL文を『作る』手法を選択すると、どうしても"ソースの見にくさ"ってのがあるように思うので、別ファイルからの

    取込みを選択しようかと思っています。

     

    sSQL001 = "SQL_SELECT_001"を指定

    sSQL001 = sSQL001.Replace("#KEY#", iKEY)

     

    上記のようなイメージをしています。(現段階ではイメージだけですが・・・)

    2009年1月8日 3:22
  • VB6.0には、Replace 関数があります。
    sql = replace(sql, "#KEY#", iKEY)

     

     

    2009年1月8日 4:12
  •  かさこ さんからの引用

    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 データベースへのパラメータ クエリを呼び出す方法

    http://support.microsoft.com/kb/200190/ja

     

     

    その上でストアド プロシージャに関して調べてみるとよいと思います。

     

    ADO で SQL Server のストアド プロシージャの値を取得する方法

    http://support.microsoft.com/kb/194792/ja

     

    Append、CreateParameter メソッドの例 (VB)

    http://msdn.microsoft.com/ja-jp/library/cc364102.aspx

2009年1月9日 8:38
  • まずデータベースに対してストアドプロシージャを作成します。
    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


    細かく説明すると長くなりすぎるため、大雑把な説明で分かりにくいかもしれません。
    わからない部分を指摘してもらえれば詳細を説明しますので、よろしくお願いします。

     

    2009年1月12日 17:07
  • おはようございます。

     

    Replace 関数で文字列を置き換えれるのは知っていますが、置き換える元になる文字列(今回の場合は複数行の文字列)を、txtファイルやiniファイルから取込む手法についてお伺いしています。

     

    もし、ご存知であればご教授願います。

    2009年1月14日 0:39
  • CatTail 様

     

    おはようございます。 ご丁寧な解説をいただきましてありがとうございます。

     

    ご教授いただいている方法ですが、やはり最初のステップとして SQL文を取込む → WHERE句等の置換 をしていきたく考えています。

     

    もし過去例がある・・・などありましたら、ご教授お願いします。
    2009年1月15日 2:33
  •  かさこ さんからの引用

    ご教授いただいている方法ですが、やはり最初のステップとして SQL文を取込む → WHERE句等の置換 をしていきたく考えています。

    そういう方向で作成するのが決まったのであれば

    とりあえず作成してみれば如何でしょう。

    他に何か分からないのでしょうか?

    2009年1月15日 3:50
  • karashima 様

     

    こんばんは。

    どのようにすれば指定したSQL文だけを取込めるかで悩んでいます。

    2009年1月15日 8:09
  • 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

     

    2009年1月15日 8:22
  •  かさこ さんからの引用

    どのようにすれば指定したSQL文だけを取込めるかで悩んでいます。

    1行ずつ読み込むなり、

    まとめて読み込んだものを1行ずつに分割するなりして

    どこからどこまでが取得したいクエリなのかを判断すればよいだけではないでしょうか。

     

    # あっ、VB6 だった・・・

    2009年1月15日 8:32
  • 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文のカンマが記入漏れしてるのは気にしないで下さい

    2009年1月15日 9:52
  • 指定したファイルから指定したキーワードの文字列を取得するって事で、以下のようなコードでどうですか?

    # テストしていないんで、バグがあったらごめんなさい。

     

    Code Snippet

    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

     

     

    # でもストアドプロシージャ方が楽だと思うけど…。

     

     

    2009年1月16日 11:50
  • CatTail 様

     

    こんばんは。 サンプルソースありがとうございます。

    今日は午後から外出していたので、週明けにでも組み込んでみます。

     

    また、つまずいたら書き込みします。。。

    2009年1月16日 12:57
  • CatTail 様

     

    おはようございます。 ご教授いただいたサンプルコードですが、新規にテストプロジェクト作成後デバッグしようとすると

    『ユーザ定義型は定義されていません』

    とコンパイルエラーが表示されます。

     

    初心者なりに考えて「参照設定で参照ライブラリの追加」が必要なのかと思われるのですが、どのようなライブラリを追加すればいいのでしょうか?(もしかすると全く違う原因かもしれませんが・・・)

    また、ライブラリの追加が必要な場合ってどのような時なのか、お分かりでしょうか?

    2009年1月19日 0:55
  • ごめんなさい。VB6のソースからコードスニペッドにコピペしたんですが、編集した際に文字を消してしまったみたいです。

    以下の部分を変更してください。

     

    Private Function GetSqlQuery(Keyword As String, Filename As strng) As String

    Private Function GetSqlQuery(Keyword As String, Filename As String) As String

    2009年1月19日 15:00
  • CatTail 様

     

    こんにちは。

    私も記述間違いに気づきませんで申し訳ありませんでした。

     

    デバッグしたところ・・・

     

        Do While EOF(n)
            ' 1行読み込んで、キーと一致したらループから抜ける
            Line Input #n, dummy_data
            If dummy_data = Keyword Then
                Exit Do
            End If
        Loop

     

    の部分で、dummy_dataには値が入っておらずブランクのようです

    2009年1月20日 6:54
  • こんばんは。

    下記のコードで指定した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

    2009年1月20日 7:39
  •  かさこ さんからの引用

        Do While (Not FileSystem.EOF(n))
            Line Input #n, dummy_data
            If dummy_data = Keyword Then
                Exit Do
            End If
        Loop
        
        ' EOFだったら対象となるキーが存在しない
        If EOF(n) = True Then

     

    最終行でExit Doしたら。。。

     

    2009年1月20日 13:24