Panggil prosedur tersimpan dengan parameter di c #

139

Saya dapat melakukan penghapusan, penyisipan, dan pembaruan dalam program saya dan saya mencoba melakukan penyisipan dengan panggilan prosedur tersimpan yang dibuat dari database saya.

Ini adalah tombol yang saya buat bekerja dengan baik.

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);
    } 

Ini adalah awal tombol untuk memanggil prosedur yang dinamai sp_Add_contactuntuk menambahkan kontak. Dua parameter untuk sp_Add_contact(@FirstName,@LastName). Saya mencari di google untuk beberapa contoh yang bagus tapi saya tidak menemukan sesuatu yang menarik.

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);
    }
FrankSharp
sumber
10
Sedikit info tambahan - Anda tidak boleh memberi nama pada aplikasi Anda yang tersimpan prosedur dengan awalan sp_, seperti di atas dengan sp_Add_contact. awalan sp_ adalah konvensi penamaan proc sistem yang disimpan, yang, ketika SQL melihatnya, akan mencari melalui semua prosedur tersimpan sistem terlebih dahulu sebelum aplikasi atau ruang pengguna disimpan procs. Mengenai kinerja, jika Anda peduli tentang itu dalam aplikasi Anda, awalan sp_ akan menurunkan waktu respons Anda.
Robert Achmann

Jawaban:

268

Ini hampir sama dengan menjalankan kueri. Dalam kode asli Anda, Anda membuat objek perintah, meletakkannya di cmdvariabel, dan tidak pernah menggunakannya. Di sini, bagaimanapun, Anda akan menggunakannya sebagai penggantida.InsertCommand .

Selain itu, gunakan a usinguntuk semua benda sekali pakai, sehingga Anda yakin bahwa benda tersebut dibuang dengan benar:

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();
    }
  }
}
Guffa
sumber
7
tetapi jika prosedur ini mengembalikan data, bagaimana cara menangkapnya di C #?
MA9H
8
@ M009: Kemudian Anda menggunakan ExecuteReaderatau ExecuteScalarmemanggilnya.
Guffa
2
@ M009: Ya, itu adalah cara lain untuk melakukan hal yang sama. Adaptor data menggunakan ExecuteReader.
Guffa
1
@DylanChen: Itu tergantung pada pengaturan database. Pengaturan default adalah bahwa pengenal tidak membedakan huruf besar / kecil.
Guffa
1
@DylanChen: Ini adalah pengaturan pemeriksaan database yang menentukan apakah pengenal peka huruf besar / kecil.
Guffa
38

Anda harus menambahkan parameter karena diperlukan untuk menjalankan 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();
    }            
}
Ravi Gadag
sumber
7
AddWithValue adalah ide yang buruk; SQL Server tidak selalu menggunakan panjang yang benar untuk nvarchar atau varchar, menyebabkan terjadinya konversi implisit. Lebih baik menentukan panjang parameter secara eksplisit, lalu menambahkan nilainya secara terpisah menggunakan parameter.Value = txtfirstname.
George Stocker
14

cmd.Parameters.Add(String parameterName, Object value)sudah usang sekarang. Sebagai gantinya gunakancmd.Parameters.AddWithValue(String parameterName, Object value)

Tambahkan (String parameterName, Object value) sudah tidak digunakan lagi. Gunakan AddWithValue (String parameterName, Object value)

Tidak ada perbedaan dalam hal fungsionalitas. Alasan mereka mencela yang cmd.Parameters.Add(String parameterName, Object value)mendukung AddWithValue(String parameterName, Object value)adalah untuk memberikan lebih banyak kejelasan. Berikut adalah referensi MSDN untuk hal yang sama

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();
    }
  }
}
Rahul Nikate
sumber
2
Apakah Anda memiliki link atau sumber ke klaim yang cmd.Parameters.Addsudah tidak digunakan lagi?
David
7
@TonyG: itu tidak benar, jawaban yang diterima menggunakan kelebihan muatan pilihan Addyang juga tidak akan digunakan lagi. AddWithValuejuga bukan cara terbaik karena menyimpulkan jenis parameter dari nilai parameter. Ini sering menyebabkan rencana eksekusi yang buruk atau konversi yang salah. Ini juga tidak memvalidasi parameter di tempat pertama (tipe fe jika Datetimetetapi Anda meneruskan a String). Anda dapat melihat di sini bahwa hanya Addyang mengambil Objectsebagai argumen kedua tidak digunakan lagi.
Tim Schmelter
2
AddWithValuememiliki fungsi yang sama dibandingkan Adddengan Object, tetapi ini bukan cara yang disukai. Keduanya perlu menyimpulkan tipenya.
Tim Schmelter
2
Anda benar sekali, @TimSchmelter. Pembacaan teks saya cacat. Terima kasih atas koreksinya. Saya sedang menulis beberapa kode baru di mana saya akan menggunakan Add (). Dan saya akan mengubah suara positif saya pada Jawaban ini menjadi suara negatif, karena Rahul Nikate sama salahnya dengan saya.
TonyG
2
@TimSchmelter Terima kasih atas saran Anda. Saya telah mengedit jawaban saya.
Rahul Nikate
3

Sebagai alternatif, saya memiliki perpustakaan yang memudahkan untuk bekerja dengan 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");
Greg R Taylor
sumber
1

Penyedia Data .NET terdiri dari sejumlah kelas yang digunakan untuk menyambungkan ke sumber data, menjalankan perintah, dan mengembalikan kumpulan data. Objek Perintah di ADO.NET menyediakan sejumlah metode Jalankan yang dapat digunakan untuk melakukan kueri SQL dalam berbagai mode.

Prosedur tersimpan adalah objek yang dapat dieksekusi yang telah dikompilasi sebelumnya yang berisi satu atau lebih pernyataan SQL. Dalam banyak kasus, prosedur tersimpan menerima parameter input dan mengembalikan beberapa nilai. Nilai parameter dapat diberikan jika prosedur tersimpan ditulis untuk menerimanya. Contoh prosedur tersimpan dengan menerima parameter input diberikan di bawah ini:

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

Prosedur tersimpan di atas menerima nama negara (@COUNTRY VARCHAR (20)) sebagai parameter dan mengembalikan semua penerbit dari negara masukan. Setelah CommandType disetel ke StoredProcedure, Anda dapat menggunakan koleksi Parameter untuk menentukan parameter.

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

Kode di atas melewatkan parameter negara ke prosedur yang tersimpan dari aplikasi 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();
        }
    }
}
Sudhakar Rao
sumber
Jawaban Anda tidak menggunakan blok yang merupakan praktik terbaik. Juga, harus ada blok coba tangkap untuk menangani pengecualian apa pun.
Dicabut
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();
        }
}
pengguna6916720
sumber
0

Inilah teknik saya yang ingin saya bagikan. Berfungsi dengan baik selama tipe properti clr Anda adalah tipe yang setara sql, misalnya. bool -> bit, panjang -> bigint, string -> nchar / char / varchar / nvarchar, desimal -> uang

public void SaveTransaction(Transaction transaction) 
{
    using (var con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConString"].ConnectionString))
    {
        using (var cmd = new SqlCommand("spAddTransaction", con))
        {
            cmd.CommandType = CommandType.StoredProcedure;
            foreach (var prop in transaction.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
                cmd.Parameters.AddWithValue("@" + prop.Name, prop.GetValue(transaction, null));
            con.Open();
            cmd.ExecuteNonQuery();
        }
    }
}
Matstar
sumber