ストアド プロシージャによるデータの変更

適用対象: .NET Framework .NET .NET Standard

ADO.NET のダウンロード

ストアド プロシージャは、入力パラメーターとしてデータを受け取り、出力パラメーター、結果セット、または戻り値としてデータを返すことができます。 以下のサンプルは、Microsoft SqlClient Data Provider for SQL Server によって入力パラメーター、出力パラメーター、および戻り値が送受信される方法を示しています。 この例では、主キー列が ID 列であるテーブルに新しいレコードを挿入します。

ストアド プロシージャを使用して SqlDataAdapterを使用してデータを編集または削除する場合は、ストアド プロシージャ定義で SET NOCOUNT ON を使用していないことを確認してください。 処理された行数がゼロとして返され、DataAdapter によってコンカレンシーの競合として解釈されてしまいます。 この場合、DBConcurrencyException が送出されます。

この例では、次のストアド プロシージャを使用して、NorthwindCategories テーブルに新しいカテゴリを挿入します。 このストアド プロシージャは CategoryName 列の値を入力パラメーターとして受け取り、SCOPE_IDENTITY() 関数を使用して ID フィールド CategoryID の新しい値を取得し、その値を出力パラメーター内に返します。 RETURN ステートメントは 、@@ROWCOUNT 関数を使用して、挿入された行数を返します。

CREATE PROCEDURE dbo.InsertCategory  
  @CategoryName nvarchar(15),  
  @Identity int OUT  
AS  
INSERT INTO Categories (CategoryName) VALUES(@CategoryName)  
SET @Identity = SCOPE_IDENTITY()  
RETURN @@ROWCOUNT  

上述の InsertCategory ストアド プロシージャを InsertCommandSqlDataAdapter のソースとして使用する例を次に示します。 @Identity 出力パラメーターは、DataSetUpdate メソッドが呼び出され、データベースにレコードが挿入された後で SqlDataAdapter に反映されます。 コードは戻り値も取得します。

using System;
using System.Data;
using Microsoft.Data.SqlClient;

class Program
{
    static void Main()
    {
        string connectionString = GetConnectionString();
        ReturnIdentity(connectionString);
        // Console.ReadLine();
    }

    private static void ReturnIdentity(string connectionString)
    {
        using (SqlConnection connection = new SqlConnection(connectionString))
        {
            // Create a SqlDataAdapter based on a SELECT query.
            SqlDataAdapter adapter = new SqlDataAdapter(
                "SELECT CategoryID, CategoryName FROM dbo.Categories", connection);

            // Create a SqlCommand to execute the stored procedure.
            adapter.InsertCommand = new SqlCommand("InsertCategory", connection);
            adapter.InsertCommand.CommandType = CommandType.StoredProcedure;

            // Create a parameter for the ReturnValue.
            SqlParameter parameter = adapter.InsertCommand.Parameters.Add("@RowCount", SqlDbType.Int);
            parameter.Direction = ParameterDirection.ReturnValue;

            // Create an input parameter for the CategoryName.
            // You do not need to specify direction for input parameters.
            adapter.InsertCommand.Parameters.Add("@CategoryName", SqlDbType.NChar, 15, "CategoryName");

            // Create an output parameter for the new identity value.
            parameter = adapter.InsertCommand.Parameters.Add("@Identity", SqlDbType.Int, 0, "CategoryID");
            parameter.Direction = ParameterDirection.Output;

            // Create a DataTable and fill it.
            DataTable categories = new DataTable();
            adapter.Fill(categories);

            // Add a new row.
            DataRow categoryRow = categories.NewRow();
            categoryRow["CategoryName"] = "New Beverages";
            categories.Rows.Add(categoryRow);

            // Update the database.
            adapter.Update(categories);

            // Retrieve the ReturnValue.
            int rowCount = (int)adapter.InsertCommand.Parameters["@RowCount"].Value;

            Console.WriteLine("ReturnValue: {0}", rowCount.ToString());
            Console.WriteLine("All Rows:");
            foreach (DataRow row in categories.Rows)
            {
                    Console.WriteLine("  {0}: {1}", row[0], row[1]);
            }
        }
    }

    static private string GetConnectionString()
    {
        // To avoid storing the connection string in your code,
        // you can retrieve it from a configuration file.
        return "Data Source=(local);Initial Catalog=Northwind;Integrated Security=true";
    }
}

関連項目