none
VB2010 OdbcConnection での4096バイト文字 RRS feed

  • 質問

  • こんにちは。

    VB2010で、OdbcConnectionを使用してデータベースを参照しています。
    データサイズが全角2048文字を超えるデータがある場合にフリーズしてしまい困っています。

    具体的には、データテーブルにFillするときもしくは、odbcDataReader.item([FieldName])で
    アクセスしたときに停止してしまい、例外もスローされない状態になります。

    VB2010でフォームにデータソースを設定、DataGridViewを配置した場合でも同様です。

    同様の現象で解決方法があれば教えていただけませんでしょうか。

    データベースはSQLServer2000、ODBCはOS付属のもの、クライアントOSはWindows7です。
    単純にVS2010からテーブル作成したものにデータ導入した場合でも発生しますので、特殊環境と
    いうことも考えにくいと思います。
    また、VisualBasic6.0などで作成した場合(ADO)にはフリーズしないことを確認しています。

    以上、よろしくお願いいたします。

    2012年11月15日 2:35

回答

  • ADO.NETという言葉の使い方が誤っていると思いますので、補足しておきます。
    OdbcConnectionは、.NET Framework Data Provider for ODBCプロバイダーで提供されるクラスであり、ADO.NETの範疇に入ります。

    ADO.NET でのデータ ソースへの接続
    http://msdn.microsoft.com/ja-jp/library/aa719513(v=vs.71).aspx


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/

    • 回答としてマーク まりおん 2012年11月16日 8:26
    2012年11月16日 8:09
    モデレータ

  • private void button1_Click(object sender, EventArgs e)
    {
        // 環境:VS2008 .NET Framework 3.5、C#、Windows7 PRO SP1 32bit
        // SQL:SQLServer2012 Express
        // sampleデータベースにtest_tテーブルを用意
        // Shift-JISで3000バイト(文字数だと2250文字)のデータを入れたものを取得
    
        string sql = "Select * from test_t";
    
        // できる
        UseADONET(sql);
    
        // できない。
        UseOdbc(sql);
    }
    
    void UseOdbc(string sql)
    {
        OdbcConnection cn;
        OdbcCommand cmd;
    
        DataTable dt = new DataTable();
    
        using (cn = new OdbcConnection(@"Driver={SQL Server};Server=localhost\sqlexpress;Integrated Security=SSPI;Database=sample;"))
        {
            cmd = new OdbcCommand(sql, cn);
            cn.Open();
            var sda = new System.Data.Odbc.OdbcDataAdapter(cmd);
            sda.Fill(dt);
            dataGridView1.DataSource = dt;
            cn.Close();
        }
    }
    
    void UseADONET(string sql)
    {
        SqlConnection cn;
        SqlCommand cmd;
    
        DataTable dt = new DataTable();
        using (cn = new SqlConnection(@"Server=localhost\sqlexpress;Integrated Security=SSPI;Database=sample;"))
        {
            cmd = new SqlCommand(sql, cn);
            cn.Open();
            var sda = new System.Data.SqlClient.SqlDataAdapter(cmd);
            sda.Fill(dt);
            dataGridView1.DataSource = dt;
            cn.Close();
        }
    }

    こんな感じで試してみましたが、確かにODBC経由だとダメな制限があるように思います(数字的にはわかりません)。
    特に理由がなければODBCをやめてADO.NETで接続してしまえば良いと思いますが、いかがでしょうか。


    追記:何も考えずC#で書いてしまいました。読み替えてください。すみません。
    • 編集済み mars12 2012年11月16日 2:03 追記
    • 回答としてマーク まりおん 2012年11月16日 7:37
    • 回答としてマークされていない まりおん 2012年11月16日 7:38
    • 回答としてマーク まりおん 2012年11月16日 7:38
    • 回答としてマークされていない まりおん 2012年11月16日 7:38
    • 回答としてマーク まりおん 2012年11月16日 8:25
    2012年11月16日 1:48
  • maris12様

    後調査頂きありがとうございました。ADO.NETで正常に動作することを確認いたしました。

    すでに存在するVB6システムのコンバージョンで拠点数も多いので、どうしてもODBCで行いたいと思っていたのですが、制限があるのであれば別の方法を考えます。

    ありがとうございました。

    • 回答としてマーク まりおん 2012年11月16日 7:42
    2012年11月16日 7:42

すべての返信


  • private void button1_Click(object sender, EventArgs e)
    {
        // 環境:VS2008 .NET Framework 3.5、C#、Windows7 PRO SP1 32bit
        // SQL:SQLServer2012 Express
        // sampleデータベースにtest_tテーブルを用意
        // Shift-JISで3000バイト(文字数だと2250文字)のデータを入れたものを取得
    
        string sql = "Select * from test_t";
    
        // できる
        UseADONET(sql);
    
        // できない。
        UseOdbc(sql);
    }
    
    void UseOdbc(string sql)
    {
        OdbcConnection cn;
        OdbcCommand cmd;
    
        DataTable dt = new DataTable();
    
        using (cn = new OdbcConnection(@"Driver={SQL Server};Server=localhost\sqlexpress;Integrated Security=SSPI;Database=sample;"))
        {
            cmd = new OdbcCommand(sql, cn);
            cn.Open();
            var sda = new System.Data.Odbc.OdbcDataAdapter(cmd);
            sda.Fill(dt);
            dataGridView1.DataSource = dt;
            cn.Close();
        }
    }
    
    void UseADONET(string sql)
    {
        SqlConnection cn;
        SqlCommand cmd;
    
        DataTable dt = new DataTable();
        using (cn = new SqlConnection(@"Server=localhost\sqlexpress;Integrated Security=SSPI;Database=sample;"))
        {
            cmd = new SqlCommand(sql, cn);
            cn.Open();
            var sda = new System.Data.SqlClient.SqlDataAdapter(cmd);
            sda.Fill(dt);
            dataGridView1.DataSource = dt;
            cn.Close();
        }
    }

    こんな感じで試してみましたが、確かにODBC経由だとダメな制限があるように思います(数字的にはわかりません)。
    特に理由がなければODBCをやめてADO.NETで接続してしまえば良いと思いますが、いかがでしょうか。


    追記:何も考えずC#で書いてしまいました。読み替えてください。すみません。
    • 編集済み mars12 2012年11月16日 2:03 追記
    • 回答としてマーク まりおん 2012年11月16日 7:37
    • 回答としてマークされていない まりおん 2012年11月16日 7:38
    • 回答としてマーク まりおん 2012年11月16日 7:38
    • 回答としてマークされていない まりおん 2012年11月16日 7:38
    • 回答としてマーク まりおん 2012年11月16日 8:25
    2012年11月16日 1:48
  • maris12様

    後調査頂きありがとうございました。ADO.NETで正常に動作することを確認いたしました。

    すでに存在するVB6システムのコンバージョンで拠点数も多いので、どうしてもODBCで行いたいと思っていたのですが、制限があるのであれば別の方法を考えます。

    ありがとうございました。

    • 回答としてマーク まりおん 2012年11月16日 7:42
    2012年11月16日 7:42
  • ADO.NETという言葉の使い方が誤っていると思いますので、補足しておきます。
    OdbcConnectionは、.NET Framework Data Provider for ODBCプロバイダーで提供されるクラスであり、ADO.NETの範疇に入ります。

    ADO.NET でのデータ ソースへの接続
    http://msdn.microsoft.com/ja-jp/library/aa719513(v=vs.71).aspx


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/

    • 回答としてマーク まりおん 2012年11月16日 8:26
    2012年11月16日 8:09
    モデレータ