1

既存のアプリを Sybase から SQL Server 2008 に変換しています。アプリは ODBC を使用してデータベースに接続します。接続文字列を変更するだけで、アプリのほとんどの機能が機能しますが、1 つだけ困惑するバグがあります。バグを示す簡単な例を作成しました。

私はストアドプロシージャを持っています:

create procedure dbo.test_sel
as 
begin
  create table #cfg
  (
    Name  varchar(100) NULL,
    Dscr  varchar(50)  NULL
  )

  insert #cfg(Name, Dscr) 
  values('Config', 'Config description')

  select COUNT(*) as [Count] from #cfg

  return 0
end

ストアド プロシージャを実行し、結果を DataTable に読み込むコード:

{
    OdbcCommand cmd = new OdbcCommand("test_sel", new OdbcConnection("Driver={SQL Server};Server=xxx;Database=xxx;Uid=xxx;Pwd=xxx"));

    DataTable dt = new DataTable();

    OdbcDataAdapter da = new OdbcDataAdapter(cmd);

    using (cmd.Connection)
    {
        da.Fill(dt);
    }

    MessageBox.Show(dt.Rows.Count.ToString());
}

メッセージには値 1 が表示され、DataTable には単一の行が含まれていると予想されます。ただし、DataTable は空です (結果セットは返されません)。

ここで、ストアド プロシージャ内のステートメントをコメント アウトしinsertてコードを再実行すると、値が 0 の count という名前の 1 つの行と 1 つの列を含む結果セットが返されます。

たとえば、一時テーブルではなく永続テーブルを使用して、ストアドプロシージャの多くのバリアントを試しましたが、同じことが発生するたびに、挿入によりストアドプロシージャが結果セットを返すのを停止します。

ODBC ドライバーを SQL Server 2008 に変更しても違いはありません。Sybase を使用している場合、および MS SQL Server Management Studio で実行している場合、コードは期待どおりに機能します。

Google検索の後、次のコードを試しました:

{
    SqlCommand cmd = new SqlCommand("test_sel", new SqlConnection("Server=xxx,5100;Database=xxx;User ID=xxx;Password=xxx"));

    DataTable dt = new DataTable();

    SqlDataAdapter da = new SqlDataAdapter(cmd);

    using (cmd.Connection)
    {
        da.Fill(dt);
    }

    MessageBox.Show(dt.Rows.Count.ToString());
}

これで機能しますが、アプリは両方のデータベースで動作する必要があるため、できる限りコードを変更したくありません。

元のコードが機能しない理由を誰かが提案できますか? シンプルで問題なく動作するように思えます。

4

1 に答える 1

1

これを機能させるために使用できるオプションが 2 つあります (私には、これはバグのように思えます。これはFill、両方OdbcDataAdapterSqlDataAdapter同じように機能するはずだからです)。

begin1)キーワードを追加した後の手順の最初に

set nocount on

2) を受け取るFillメソッドではDataSetなく、パラメーターとして受け取るメソッドのオーバーロードを使用しますDataTable

MSDN の状態: DataTable をパラメーターとして受け取る Fill のオーバーロードは、最初の結果のみを取得します

INSERTが実行されてオフになっている場合NOCOUNT、ステートメントによって影響を受けた行数に関する情報が返されます。したがって、このオプションをオフにすると、行数は 2 回報告されます (SSMS の [メッセージ] ウィンドウで確認できます)。1 回は INSERT で、2 回目は SELECT です。最初の行数 (INSERT から) が何らかの形で最初の結果セットとして解釈されるようです。この行数はINSERTステートメントを参照していないSELECTため、返される行はありません。

于 2013-02-22T09:07:03.220 に答える