質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.79%

VB ローカルDB(.mdf) ファイルにSQL serverから テーブルごとデータを引っ張りたい。

解決済

回答 1

投稿

  • 評価
  • クリップ 2
  • VIEW 3,862

score 45

Dim rs As New ADODB.Recordset
Dim rs2 As New ADODB.Recordset
Dim cn As String : cn = "Provider='SQLOLEDB';Data Source='IPアドレス';Initial Catalog='サーバー名';User ID='myID';Password='パスワード'"

Dim cn2 As String : cn2 = "Data Source=.\SQLEXPRESS;AttachDbFilename=ローカル.mdfフルパス;Integrated Security=True;MultipleActiveResultSets=True;User Instance=True"

Dim strSQL As String
Dim strSQL2 As String
strSQL = "SELECT * FROM [マスターテーブル]"
strSQL2 = "SELECT * FROM [ローカルテーブル]"
rs.Open(strSQL, cn, ADODB.CursorTypeEnum.adOpenStatic, ADODB.LockTypeEnum.adLockOptimistic)

If rs.EOF = False Then'マスターテーブルがあったなら
Dim Con As New SqlConnection
Dim sqlCommand As SqlCommand = Nothing
Dim sqlReader As SqlDataReader = Nothing
Con.ConnectionString = cn2

Try
Con.Open()
Debug.Print("オープン成功")

sqlCommand = New SqlCommand("DELETE FROM [ローカルテーブル]", Con) '削除
Dim myint As Integer : myint = sqlCommand.ExecuteNonQuery '実行

ここまでうまくいっています。
SQLserverに マスターがあったらローカルのmdfファイルを空にして…
こっから マスターテーブルごと更新したいんですが… うまくいっていません。
この先の書き方… または、もっときれいな書き方教えてください。

            

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • twck

    2016/09/06 20:49

    2つ質問させてください。
    質問1つ目:「マスターテーブルがあったなら」と書いてありますが、これは「マスターテーブルの中にデータが1件以上あったなら」ですか?それとも「データが0件でもマスターテーブルが存在さえしていたら」ですか?
    質問2つ目:テーブルの中のフィールド名はプログラムを作っている段階で分かっていますか?それとも実行するときまで分かりませんか?

    キャンセル

回答 1

checkベストアンサー

0

質問文に書かれていないことは想像で作成しました。
ADO と ADO.NET が混在しているので ADO.NET に統一しました。
マスターテーブルがあるかどうかのチェックはしません。
VB6 から移植したと思われるコードは VB.NET風に書き直しました。
マスターテーブルのフィールド名は自動で取得するようにしました。
マスターテーブルとローカルテーブルのフィールドは同じであるものとします。
サンプルコードなので例外処理はしていません。

'Connection String 接続文字列
Dim cs1 = "Data Source=IPアドレス;Initial Catalog=データベース名;Persist Security Info=True;User ID=ユーザーID;Password=パスワード"
Dim cs2 = "Data Source=.\SQLEXPRESS;AttachDbFilename=ローカル.mdfフルパス;Integrated Security=True;MultipleActiveResultSets=True;User Instance=True"

'マスターテーブルとローカルテーブルのテーブル名
Dim tableName1 = "マスターテーブル名"
Dim tableName2 = "ローカルテーブル名"

'マスターDBとローカルDBのオープン
Using db1 As New SqlConnection(cs1), db2 As New SqlConnection(cs2)
    db1.Open()
    db2.Open()

    'ローカルテーブルのデータを削除する
    Dim cmd2 = db2.CreateCommand()
    cmd2.CommandText = "DELETE FROM " & tableName2
    cmd2.ExecuteNonQuery()

    'マスターテーブルのデータを読み込む
    Dim cmd1 = db1.CreateCommand()
    cmd1.CommandText = "SELECT * FROM " & tableName1
    Using reader = cmd1.ExecuteReader

        '読み込んだスキーマ情報からフィールド名を取得してリスト化する
        '読み込んだスキーマ情報からフィールド名とデータ型を取得してパラメーターを作る
        Dim listFieldName As New List(Of String)
        Dim params2 = cmd2.Parameters
        params2.Clear()
        For Each row As System.Data.DataRow In reader.GetSchemaTable.Rows

            'フィールド名のリスト化
            Dim fieldname = row("ColumnName").ToString
            listFieldName.Add(fieldname)

            'パラメーターの生成
            Dim sqlDbType = DirectCast(row("ProviderType"), SqlDbType)
            params2.Add(New SqlParameter(fieldname, sqlDbType))
        Next

        'リスト化したフィールド名を使用して INSERT文を作成する
        Dim arrayFields = listFieldName.ToArray()
        cmd2.CommandText = "INSERT INTO " & tableName2 & " (" & _
            String.Join(", ", arrayFields) & _
            ") VALUES (@" & _
            String.Join(", @", arrayFields) & _
            ")"

        'マスターテーブルのデータを1件ずつ読み込みローカルテーブルにINSERTする
        Do While reader.Read

            '全フィールドの値をパラメーターにセットする
            For index As Integer = 0 To params2.Count - 1
                params2(index).Value = reader(index)
            Next

            'INSERT文を発行する
            cmd2.ExecuteNonQuery()
        Loop
    End Using
End Using

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/09/07 22:24

    twckさん!!
    質問返す タイミング 遅れて申し訳ございません。
    質問の回答としては…マスターテーブルの中にデータが1件以上あったなら
    テーブルの中のフィールド名はプログラムを作っている段階で分かっています

    ありがとうごさいます。大変参考になりました。
    ADO と ADO.NETの違いすら理解してませんでした!!

    この問題はtwckさんよって解決されましたが
    もう初心者なので次から次へと困っています。。。
    https://teratail.com/questions/47172?complete=

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.79%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る