VB6と2008、SQL使用方法の違いについて

このQ&Aのポイント
  • VB6とVB2008でのデータベースの使用方法には違いがあります。VB6ではVB6のSQLを使用していたが、VB2008ではSQLステートメントを直接使用します。
  • VB6では複数のフィールドを持つレコードの保存処理をプロシージャで行っていましたが、VB2008ではSQLのINSERT文を使用します。
  • VB2008での保存処理はコマンドテキストに長文のステートメントを記述することになります。VB6のように別のプロシージャで保存処理を行う方法はありません。.NETではコーディングが必要です。
回答を見る
  • ベストアンサー

VB6と2008、SQL使用方法の違いについて

最近VB2008を始めた初心者です。データベースはアクセスです。 これまでは、VB6.0にてデータベースへの書き込みを行う際は、VB6のSQLを使用していました。1つのレコードに複数のフィールドがある場合も、以下のようなプロシージャを作成し処理の共有を行っておりました。 UserMaster!Name=Textbox1.Text UserMaster!ID=Textbox2.Text UserMaster!Collection1=Textbox3.Text UserMaster!Collection2=Textbox4.Text UserMaster!Collection3=Textbox5.Text ・・・ そして、VB2008に移行後はSQLステートメントを以下のようにそのまま使用しております。 cmnd.CommandText = "INSERT INTO Work (Id,Collection1,Collection2・・・) " & _ " VALUES ('" & Textbox1.Text & "','" & Textbox2.Text & "'," & Textbox3.Text & ・・・)" cmnd.ExecuteNonQuery() しかし、このようにコマンドテキストにて保存を行う場合、同一レコードに多数のフィールドがある場合、ステートメントが長文になってしまいます。 VB6のように保存処理を別にプロシージャにて実行させる方法は何かないでしょうか? .NETでは根気よくコーディングしていくしかないのでしょうか? アドバイス願います。m(_ _ )m

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

> >まぁ,現在の常識として入力値をそのままSQL文として組み立てない,というのはありますが……。 > これはどういった意味なのでしょうか。具体的に説明して頂ければ幸いです。 入力値をそのまま使うと,SQL Injectionの可能性がでます。 例えば,Textbox1.Textが"','','', ... );DELETE FROM Work;--"だったような場合,DELETE FROM Workによってデータが削除されてしまいます。 SELECT系だと,条件式を無視するような記述方法も可能で,情報漏洩の原因になり得ます。 実際にSQL Injectionによる情報流出が疑われる事例はよく起きています。 こういうことを防ぐために,ADO.NETではデータをパラメータ化し,サーバー側でバインドさせます。 cmnd.CommandText = "INSERT INTO Work ( Id, Collection1, Collection2, ... ) VALUES ( @id, @collection1, @collection2, ... )" cmnd.Parameters.Add("@id", SqlDbType.Int).Value = Int32.Parse(Textbox1.Text) cmnd.Parameters.Add("@collection1", SqlDbType.VarChar, 64).Value = Textbox2.Text ... cmdn.ExecuteNonQuery() SQL インジェクション対策でプリペア-ドステートメントやバインド機構を使うことは, 10年近く前から言われていることなので,「現在の常識」と書きました。 もちろん,すべての入力値の文字種に制限があり,それがチェック済みで, SQL Injectionを引き起こさないのであればバインドしなくてもよいのですが, 入力値の文字種の制限はアプリケーション側の制限であり,SQL Injectionを理由とする制限ではないため, その場合であってもバインド機構を使うことが推奨されます。

komorebi88
質問者

お礼

パラメータ化についてのご説明とても参考になりました。 丁寧に書いて頂きありがとうございます。

その他の回答 (1)

回答No.1

Visual BasicはRDBMSではないので,「VB6のSQL」は存在しないと思いますが……。 Visual Basic 7以降にもちゃんとメソッド (Sub/Function) は存在します。 クラスを受け付けて単一のSQLステートメントを実行するメソッドや, IEnumerable<T>を受け付けて複数のSQLステートメントを実行するメソッドを作ることは多々あります。 後者はPrepareが使えるので,効率をよくする効果もあります。 ---- まぁ,現在の常識として入力値をそのままSQL文として組み立てない,というのはありますが……。 # ADO.NETならパラメータ化してバインドさせる。

komorebi88
質問者

お礼

ご返答ありがとうございます。 ところで、 >まぁ,現在の常識として入力値をそのままSQL文として組み立てない,というのはありますが……。 これはどういった意味なのでしょうか。具体的に説明して頂ければ幸いです。

関連するQ&A

  • 多数のフィールドをSQLで書き込む方法?(VB08

    VB2008にてアクセスMDBに対し、SQL文を使用し、特定のテーブルの1レコードへ多数の項目(フィールド)を書き込む際に効率的な方法はないでしょうか? 仮に100項目だとして、INSERT INTO文がとても長くなってしまう代わりに、処理を分散させるコーディング方法は何かないでしょうか?

  • VBでSQL文のUPDATE構文を使った時のエラーについて

    こんにちは。全くのVB初心者ですが回答、ご指摘のほうよろしければお願いします。 Microsoft Visual Studio 2005でデータベース管理のアプリケーションを制作しているんですが、エラーが出て困っています。 本フォームの各Textboxの編集した値を、 利用者カルテフォーム(別フォーム)のDataGridViewとデータベースに反映させるというプログラミングにしようとしています。 以下のコードでデバッグしようとしても「UPDATE ステートメントの構文エラーです。」というエラーメッセージが出てきて実行できない状態です。 VB中学校というサイトのデータベース講座を参考にしました。 ------------------------------------------------------------ Private Sub Button5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim Cn As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:xxxx.mdb") Dim SQLCm As OleDbCommand = Cn.CreateCommand Dim Table As DataTable = DirectCast(利用者カルテDataGridView1.DataSource, DataTable) Dim Row As DataRow Dim Adapter As New OleDbDataAdapter(SQLCm) Row = Table.NewRow Row("No") = NotextBox.Text Row("名前") = 名前TextBox.Text Row("フリガナ") = フリガナTextBox.Text Table.Rows.Add(Row) Dim SQL As String = "" SQL = "UPDATE 患者データ SET " SQL &= " No = " & Row("No") & "', " SQL &= " 名前 = '" & Row("名前") & "', " SQL &= " フリガナ= " & Row("フリガナ") & "', " SQL &= " WHERE " SQL &= " No = " & NotextBox.Text SQLCm.CommandText = SQL Cn.Open() ※SQLCm.ExecuteNonQuery() Cn.Close() 利用者カルテ.Show() Table.Dispose() Adapter.Dispose() SQLCm.Dispose() Cn.Dispose() End Sub ---------------------------------------------------------- 以上が実際にエラーがでる部分になります。 ※の部分で「UPDATE ステートメントの構文エラーです。」というエラーが指摘されています。 ちなみに他のフォームでINSERT文も使っているのですが、そちらは問題なく実行できる状態です。 初歩的な質問で申し訳ないですが、よければ回答のほうよろしくお願いします。

  • VBで使用するAccessのSQL(INSERT文)

    VBで使用するAccessのSQL(INSERT文)ですが、 下記のようなSQLはどのようにすれば良いのでしょうか? テーブル:A フィールド:B(Text型),C(Yes/No型) 作成したいSQL文: Textに空白、Yes/NoはTrueを入れ、 既存のフィールド内の一番下に 作成(追加)する。

  • VB.netでmdbのレコードを取得

    VB.netからAccessで作成したデータベースのレコードを 取得するプログラムを作りたいと考えています。 ですが、データベースを操作するプログラムは初めてですので、 どうもイメージがわきません。 やりたいことは、 1.VBからmdbにアクセス(DAO) 2.SELECTでレコードを取得 3.取得したレコードから必要なフィールドをテキストボックに表示 上記の処理が可能であれば、コーディングのヒントを頂けないでしょうか? よろしくお願いします --- OS:Windows Vista 開発環境:VS2005 pro

  • VBでACCESS(アクセス)にSQLを発行したときのエラーについて

    VBでアクセスのデータにSQLを発行してテーブルに更新等の処理をしています、削除や検索では該当するレコードがないとエラーコードが返りますが、挿入の場合はすでにあるデータに重複するデータを登録する(二重登録)処理をしてもエラーになりません? なにもメッセージがないので登録されたのか、だめだったのかを判断することができません、このような場合に二重登録の判定をするには先に検索をして当該データの有無を調べた後に登録処理にを行うようにするしかないのでしょうか?(同じことが更新についてもあてはまります) データの挿入にはjetSQLのinsert intoステートメントを使用しています データの更新には同updateステートメントを使用しています

  • VBでSQL

    SQLでテーブル1に該当レコードがなければインサート あればアップデートをする処理をしたいのです IF ??? THEN UPDATE テーブル1 SET SELECT * FROM テーブル2 WHERE 条件 ELSE INSERT INTO テーブル1(SELECT * FROM テーブル2) END IF ???はプライマリキーで判定をしようと考えています こんな感じでやろうとしたところ うまくいきませんでした VB上で実行しよううとしているからなのでしょうか? ADOでSQLサーバに接続しています 条件分岐もどういう条件(VBでの書き方)がわからないです。 よろしくお願いします。

  • VB2008EE でSQLステートをアダプターにセットできない?

    VB歴の浅い素人です。宜しくお願いします。 データベース管理でSQL ServerからAccessデータベースファイルに変えたら下記の実行が出来なくなりました。 ************************************************************** sql = "SELECT 入先名 FROM 入先マスタ WHERE 入先名 LIKE '%AA%')" 'データアダプタにSQLステートメントを設定する Dim da As New SqlClient.SqlDataAdapter(sql,My.Settings.E3DTSR01ConnectionString) 'データテーブルをクリアする Me.XXXX01DataSet.入先マスタ.Clear() 'データテーブルにデータアダプタを介してデータをセットする da.Fill(Me.XXXX01DataSet.入先マスタ) ************************************************************ 上記ソースの「データアダプタにSQLステートメントを設定する」 ところでエラーになり、 キーワードはサポートされていません : 'provider' となります。 ちなみにSQLステートメント単体テストではOKでした。 またAccessにする前は動作していました。 本当は、テキスト文を入力させキーワード絞込みを作る予定なのですが Accessデータベースだと WHERE XXDB LIKE %" & txtName.Text & "%' のような間接的な事がうまくいきません。(クエリの追加でも) LIKE @filtername としてもエラーになります。 何か?Access専用のやり方があるのでしょうか? とても困っております。宜しくお願いします。

  • VB2010のSQLを使ったレコードカウント方法

    VB2010にて他のシステムから出力したCSVファイルにアクセスして集計を行おうとしています。 重複を排除したカウントを得たいのですがうまくいきません。 (1) SQL = "SELECT DISTINCT 物品ID FROM …" だと目的のレコードを抽出できるのですがCOUNTを使って (2) SQL = "SELECT COUNT(DISTINCT 物品ID) AS 物品数 FROM …" とする『演算子がありません』とエラーが出て (3) SQL = "SELECT DISTINCT COUNT(物品ID) AS 物品数 FROM …" とすると値はですのですが(1)のレコード数と違う数が出てきます??? 素人の手探りでプログラミングをしているので動きの違いが分かりません ご教授お願いします。

  • SQL INSERTの使い方を教えてください

    vb2008でアクセスへデータを書き込む部分のコードを書こうとしているのですが、SQLのINSERT構文を使って連続した10レコードをテーブルへINSERTしたいのですが1つわからないところがあります。例えば、あるフィールドで、1番目のレコードだけアイテムが入り、残りは書き込む必要がない場合、Do~Loopなど使用しINSERT構文にて書き込み処理する場合、どのように条件わけするとすっきり書けるでしょうか・・・?いい感じのロジックがあればご教授願います。

  • sqlでのIIFの使用方法

    accsessのテーブルデータで4列10000レコードのデータを作成し 先頭列にチェックボックスを配置したうえでvb2008 express editionで作成したソフトのdatagridview上でデータを表示し、使う人がチェックボックスをチェックすることにより、選択したレコードデータを別ファイルに保存できるようにしています。mdbのテーブル名は"No1"です。データ連結はdatatableを使用しています。そこで、datagridviewのチェックボックスの変化をmdbテーブルに反映させる処理をdatagridviewのcellcontentclickイベントに Dim Cn As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & basePath) Dim SQLCM As OleDbCommand = Cn.CreateCommand SQLCM.CommandText = "UPDATE No1 SET iif(チェック = False, チェック = True , チェック = False) WHERE ID = " & e.RowIndex + 1 Cn.Open() SQLCM.ExecuteNonQuery() Cn.Close() と書き込んで処理しようとしていますが、UPDATEステートメント構文エラーと表示され処理できません。TRUEに変更する処理は Dim Cn As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & basePath) Dim SQLCM As OleDbCommand = Cn.CreateCommand SQLCM.CommandText = "UPDATE No1 SET チェック = True WHERE ID = " & e.RowIndex + 1 Cn.Open() SQLCM.ExecuteNonQuery() Cn.Close() でうまくいってます。IIFの使用方法が間違っていると思うのですが。どなたかお教えねがえないでしょうか。開発環境は、Vista Home premium、mdbはaccess2003で作成しています。

専門家に質問してみよう