C#のパラメーターを使用してストアドプロシージャを呼び出す


138

プログラムで削除、挿入、更新を行うことができ、データベースから作成されたストアドプロシージャを呼び出して挿入を試みます。

これは私がうまく機能するボタンインサートです。

private void btnAdd_Click(object sender, EventArgs e)
{
        SqlConnection con = new SqlConnection(dc.Con);
        SqlCommand cmd = new SqlCommand("Command String", con);

        da.InsertCommand = new SqlCommand("INSERT INTO tblContacts VALUES (@FirstName, @LastName)", con);
        da.InsertCommand.Parameters.Add("@FirstName", SqlDbType.VarChar).Value = txtFirstName.Text;
        da.InsertCommand.Parameters.Add("@LastName", SqlDbType.VarChar).Value = txtLastName.Text;

        con.Open();
        da.InsertCommand.ExecuteNonQuery();
        con.Close();

        dt.Clear();
        da.Fill(dt);
    } 

これは、sp_Add_contact連絡先を追加するための名前のプロシージャを呼び出すボタンの開始です。の2つのパラメータsp_Add_contact(@FirstName,@LastName)。グーグルで良い例を検索しましたが、興味深いものは何も見つかりませんでした。

private void button1_Click(object sender, EventArgs e)
{
        SqlConnection con = new SqlConnection(dc.Con);
        SqlCommand cmd = new SqlCommand("Command String", con);
        cmd.CommandType = CommandType.StoredProcedure;

        ???

        con.Open();
        da. ???.ExecuteNonQuery();
        con.Close();

        dt.Clear();
        da.Fill(dt);
    }

8
少しだけ情報を追加します。アプリケーションのストアドプロシージャには、上記のsp_Add_contactのように、sp_プレフィックスを付けないでください。sp_プレフィックスは、システムストアドプロシージャの命名規則であり、SQLがそれを検出すると、アプリケーションまたはユーザースペースストアドプロシージャの前にすべてのシステムストアドプロシージャを最初に検索します。パフォーマンスの問題として、アプリケーションでそれを気にする場合、sp_プレフィックスは応答時間を低下させます。
Robert Achmann、2014年

回答:


265

クエリを実行するのとほとんど同じです。元のコードでは、コマンドオブジェクトを作成し、それをcmd変数に入れて、決して使用しません。ただし、ここではの代わりに使用しますda.InsertCommand

また、usingすべての使い捨てオブジェクトにa を使用して、それらが適切に破棄されることを確認します。

private void button1_Click(object sender, EventArgs e) {
  using (SqlConnection con = new SqlConnection(dc.Con)) {
    using (SqlCommand cmd = new SqlCommand("sp_Add_contact", con)) {
      cmd.CommandType = CommandType.StoredProcedure;

      cmd.Parameters.Add("@FirstName", SqlDbType.VarChar).Value = txtFirstName.Text;
      cmd.Parameters.Add("@LastName", SqlDbType.VarChar).Value = txtLastName.Text;

      con.Open();
      cmd.ExecuteNonQuery();
    }
  }
}

7
しかし、このプロシージャがデータを返す場合、どのようにC#でそれをキャッチできますか
MA9H 2013

8
@ M009:ExecuteReaderまたはExecuteScalarを使用して呼び出します。
Guffa 2013

2
@ M009:はい、それは同じことを行う別の方法です。データアダプターはを使用しExecuteReaderます。
Guffa 2013

1
@DylanChen:データベースの設定によって異なります。デフォルト設定では、識別子は大文字と小文字を区別しません。
グッファ2016年

1
@DylanChen:識別子が大文字小文字を区別するかどうかを決定するのはデータベースの照合設定です。
グッファ2016年

36

SPを実行するために必要なため、パラメーターを追加する必要があります

using (SqlConnection con = new SqlConnection(dc.Con))
{
    using (SqlCommand cmd = new SqlCommand("SP_ADD", con))
    {
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.AddWithValue("@FirstName", txtfirstname.Text);
        cmd.Parameters.AddWithValue("@LastName", txtlastname.Text);
        con.Open();
        cmd.ExecuteNonQuery();
    }            
}

7
AddWithValueは悪い考えです。SQL Serverは、常にnvarcharまたはvarcharに正しい長さを使用するとは限らず、暗黙的な変換が発生します。パラメータの長さを明示的に指定してから、を使用して値を個別に追加することをお勧めしparameter.Value = txtfirstnameます。
ジョージストッカー2014年

14

cmd.Parameters.Add(String parameterName, Object value)は非推奨になりました。代わりにcmd.Parameters.AddWithValue(String parameterName, Object value)

Add(String parameterName、Object value)は廃止されました。AddWithValue(String parameterName、Object value)を使用します

機能面での違いはありません。彼らcmd.Parameters.Add(String parameterName, Object value)が賛成することを廃止した理由AddWithValue(String parameterName, Object value)は、より明確にするためです。これは同じのMSDNリファレンスです

private void button1_Click(object sender, EventArgs e) {
  using (SqlConnection con = new SqlConnection(dc.Con)) {
    using (SqlCommand cmd = new SqlCommand("sp_Add_contact", con)) {
      cmd.CommandType = CommandType.StoredProcedure;

      cmd.Parameters.AddWithValue("@FirstName", SqlDbType.VarChar).Value = txtFirstName.Text;
      cmd.Parameters.AddWithValue("@LastName", SqlDbType.VarChar).Value = txtLastName.Text;

      con.Open();
      cmd.ExecuteNonQuery();
    }
  }
}

2
cmd.Parameters.Add廃止された申し立てへのリンクまたは情報源はありますか?
David

7
@TonyG:それは真実Addではありません、受け入れられた回答は推奨されるオーバーロードを使用しますが、そのオーバーロードも非推奨ではありません。 AddWithValueパラメータのタイプからパラメータのタイプを推測するため、これも最良の方法ではありません。これは、多くの場合、実行計画の誤りや誤った変換につながります。また、そもそもパラメーターの検証は行いません(fe型の場合Datetimeはを渡しますString)。ここAddでは、Objectasを2番目の引数としてのみ使用することが推奨されていないことがわかります
Tim Schmelter、2015年

2
AddWithValueの機能はAddと同じですがObject、推奨される方法ではありません。どちらも型を推測する必要があります。
Tim Schmelter、2015年

2
@TimSchmelter、あなたは絶対的に正しいです。私のテキストの読みに欠陥があった。訂正ありがとうございます。Add()を使用する新しいコードを書いています。そして、私はこの回答に対する私の賛成票を反対票に変更します。RahulNikateが私と同じように間違っていたからです。
TonyG、2015年

2
@TimSchmelterアドバイスありがとうございます。回答を編集しました。
Rahul Nikate、2015年

3

別の方法として、procsでの作業を容易にするライブラリがあります。https//www.nuget.org/packages/SprocMapper/

SqlServerAccess sqlAccess = new SqlServerAccess("your connection string");
    sqlAccess.Procedure()
         .AddSqlParameter("@FirstName", SqlDbType.VarChar, txtFirstName.Text)
         .AddSqlParameter("@FirstName", SqlDbType.VarChar, txtLastName.Text)
         .ExecuteNonQuery("StoredProcedureName");

0
public void myfunction(){
        try
        {
            sqlcon.Open();
            SqlCommand cmd = new SqlCommand("sp_laba", sqlcon);
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.ExecuteNonQuery();
        }
        catch(Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
        finally
        {
            sqlcon.Close();
        }
}

0

.NETデータプロバイダーは、データソースへの接続、コマンドの実行、およびレコードセットの返却に使用されるいくつかのクラスで構成されています。ADO.NETのコマンドオブジェクトは、さまざまな方法でSQLクエリを実行するために使用できる多数のExecuteメソッドを提供します。

ストアード・プロシージャーは、1つ以上のSQLステートメントを含む、事前にコンパイルされた実行可能オブジェクトです。多くの場合、ストアドプロシージャは入力パラメータを受け入れ、複数の値を返します。パラメータ値は、それを受け入れるようにストアドプロシージャが記述されている場合に指定できます。入力パラメーターを受け入れるサンプルストアドプロシージャを以下に示します。

  CREATE PROCEDURE SPCOUNTRY
  @COUNTRY VARCHAR(20)
  AS
  SELECT PUB_NAME FROM publishers WHERE COUNTRY = @COUNTRY
  GO

上記のストアドプロシージャは、国名(@COUNTRY VARCHAR(20))をパラメーターとして受け入れ、入力国からすべての発行元を返します。CommandTypeをStoredProcedureに設定すると、Parametersコレクションを使用してパラメーターを定義できます。

  command.CommandType = CommandType.StoredProcedure;
  param = new SqlParameter("@COUNTRY", "Germany");
  param.Direction = ParameterDirection.Input;
  param.DbType = DbType.String;
  command.Parameters.Add(param);

上記のコードは、C#アプリケーションからストアード・プロシージャーに国パラメーターを渡します。

using System;
using System.Data;
using System.Windows.Forms;
using System.Data.SqlClient;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            string connetionString = null;
            SqlConnection connection ;
            SqlDataAdapter adapter ;
            SqlCommand command = new SqlCommand();
            SqlParameter param ;
            DataSet ds = new DataSet();

            int i = 0;

            connetionString = "Data Source=servername;Initial Catalog=PUBS;User ID=sa;Password=yourpassword";
            connection = new SqlConnection(connetionString);

            connection.Open();
            command.Connection = connection;
            command.CommandType = CommandType.StoredProcedure;
            command.CommandText = "SPCOUNTRY";

            param = new SqlParameter("@COUNTRY", "Germany");
            param.Direction = ParameterDirection.Input;
            param.DbType = DbType.String;
            command.Parameters.Add(param);

            adapter = new SqlDataAdapter(command);
            adapter.Fill(ds);

            for (i = 0; i <= ds.Tables[0].Rows.Count - 1; i++)
            {
                MessageBox.Show (ds.Tables[0].Rows[i][0].ToString ());
            }

            connection.Close();
        }
    }
}

あなたの答えは、ベストプラクティスであるブロックの使用使用していません。また、例外を処理するためのtry catchブロックが必要です。
18
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.