執筆者: インフォシェア株式会社 小高 太郎

動作確認環境: .NET Framework2.0 以上、Visual Studio 2005 以上


ADO.NET でストアド プロシージャを呼び出すには Command オブジェクトを用います。このときパラメーターや戻り値の受け渡しには、その種類によっていくつかの手法が存在します。ここでは代表的な手法についてご紹介します。

あらかじめ、SQL Server のサンプル データベース Northwind に、以下のストアド プロシージャを作成しておきます。

CREATE PROCEDURE [dbo].[Most Expensive Products]
@COUNT INT,
@SUM INT OUTPUT
AS
SET ROWCOUNT @COUNT
 
SELECT @SUM = SUM(Products.UnitPrice)FROM Products
SELECT Products.ProductName, Products.UnitPrice FROM Products
RETURN 0

このストアド プロシージャは、インプット引数、アウトプット引数、結果セット、戻り値と 4 種類の情報を受け渡しするようになっています。

上記のストアド プロシージャを呼び出すコードは以下のようになります。

C#
using System.Data.SqlClientusing System.Data; 
 
static void Main(string[] args) 
{ 
    using (SqlConnection cn = new SqlConnection()) 
    { 
        cn.ConnectionString = @"Data Source=.;Initial Catalog=Northwind;Integrated Security=True"; 
        cn.Open(); 
 
        SqlCommand cmd = new SqlCommand("Most Expensive Products", cn); 
        cmd.CommandType = CommandType.StoredProcedure; 
        cmd.Parameters.Add(new SqlParameter("COUNT", SqlDbType.Int)); 
        cmd.Parameters["COUNT"].Direction = ParameterDirection.Input; 
        cmd.Parameters["COUNT"].Value = 10; 
 
        cmd.Parameters.Add(new SqlParameter("SUM", SqlDbType.Int)); 
        cmd.Parameters["SUM"].Direction = ParameterDirection.Output; 
 
        cmd.Parameters.Add(new SqlParameter("ReturnValue", SqlDbType.Int)); 
        cmd.Parameters["ReturnValue"].Direction = ParameterDirection.ReturnValue; 
 
        SqlDataReader dr = cmd.ExecuteReader(); 
        while (dr.Read()) 
        { 
            Console.WriteLine("結果セット:" + dr[0]); 
        } 
        dr.Close(); 
 
        int returnValue = ((int)cmd.Parameters["ReturnValue"].Value); 
        Console.WriteLine("戻り値:" + returnValue.ToString()); 
 
        int sum = ((int)cmd.Parameters["SUM"].Value); 
        Console.WriteLine("アウトプット引数:" + sum.ToString()); 
    } 
} 
 

このコードでは、結果セットを取得するために ExecuteReader メソッドでストアド プロシージャを実行し、その戻り値を DataReader として受けます。戻り値やアウトプット引数を取得する前に、DataReader を Close する必要があります。

今回は、複数行、複数列が存在する結果セットでしたが、結果セットが 1 行 1 列の場合、ExecuteScalar で実行する事も可能です。また、結果セットが必要ないのであれば、ExecuteNonQuery での実行も可能です。(結果セットが存在しても ExecuteScalar や ExecuteNonQuery でのストアド プロシージャ実行は可能ですが、その場合、返される行は破棄されます。)

更に非接続型の DataSet(DataTable) で結果セットを受け取る事も可能です。上記の SqlDataReader dr = cmd.ExecuteReader(); から、dr.Close(); までを以下にように変更します。

C#
SqlDataAdapter da = new SqlDataAdapter (cmd); 
DataSet ds = new DataSet (); 
da.Fill(ds); 
foreach (DataRow rw in ds.Tables[0].Rows) 
{ 
    Console.WriteLine("結果セット:" + rw[0].ToString()); 
} 
 

上記の実行結果は以下になります。

図 1

参考リンク


Code Recipe

ページのトップへ