既存のアプリを 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());
}
これで機能しますが、アプリは両方のデータベースで動作する必要があるため、できる限りコードを変更したくありません。
元のコードが機能しない理由を誰かが提案できますか? シンプルで問題なく動作するように思えます。