เรียกกระบวนงานที่เก็บไว้พร้อมพารามิเตอร์ใน 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เพื่อเพิ่มผู้ติดต่อ sp_Add_contact(@FirstName,@LastName)ทั้งสองพารามิเตอร์สำหรับการ ฉันค้นหาด้วย google สำหรับตัวอย่างที่ดี แต่ฉันพบว่าไม่มีอะไรน่าสนใจ

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_ เช่นด้านบนด้วย sp_Add_contact คำนำหน้า sp_ คือระบบที่จัดเก็บแบบแผนการตั้งชื่อ proc ซึ่งเมื่อ SQL เห็นจะค้นหาขั้นตอนการจัดเก็บระบบทั้งหมดก่อนก่อนที่แอปพลิเคชันหรือพื้นที่ผู้ใช้ใด ๆ ที่จัดเก็บ procs ตามประสิทธิภาพหากคุณใส่ใจในแอปพลิเคชันของคุณคำนำหน้า sp_ จะทำให้เวลาตอบสนองของคุณลดลง
Robert Achmann

คำตอบ:


265

มันค่อนข้างเหมือนกับการเรียกใช้แบบสอบถาม ในรหัสต้นฉบับของคุณคุณกำลังสร้างวัตถุคำสั่งวางไว้ในcmdตัวแปรและไม่เคยใช้มัน นี่ da.InsertCommandแต่คุณจะใช้ที่แทน

นอกจากนี้ให้ใช้usingสำหรับวัตถุที่ใช้แล้วทิ้งทั้งหมดเพื่อให้แน่ใจว่าพวกมันถูกกำจัดอย่างถูกต้อง:

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

8
@ M009: จากนั้นคุณใช้ExecuteReaderหรือExecuteScalarโทร
Guffa

2
@ M009: ใช่นั่นเป็นอีกวิธีหนึ่งในการทำสิ่งเดียวกัน ExecuteReaderใช้อะแดปเตอร์ข้อมูล
Guffa

1
@DylanChen: ขึ้นอยู่กับการตั้งค่าฐานข้อมูล การตั้งค่าเริ่มต้นคือตัวระบุไม่ใช่แบบตัวพิมพ์เล็กและใหญ่
Guffa

1
@DylanChen: เป็นการตั้งค่าการเปรียบเทียบของฐานข้อมูลที่กำหนดว่าตัวระบุเป็นแบบตัวพิมพ์เล็กหรือใหญ่
Guffa

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ดีกว่าที่จะระบุความยาวของพารามิเตอร์อย่างชัดเจนแล้วเพิ่มค่าใช้แยกต่างหาก
George Stocker

14

cmd.Parameters.Add(String parameterName, Object value)เลิกใช้แล้วในขณะนี้ ใช้แทนcmd.Parameters.AddWithValue(String parameterName, Object value)

เพิ่ม (พารามิเตอร์ String ชื่อค่าวัตถุ) ได้รับการคัดค้าน ใช้ AddWithValue (พารามิเตอร์ String ชื่อค่าวัตถุ)

ไม่มีความแตกต่างในแง่ของการใช้งาน เหตุผลที่พวกเขาเลิกใช้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แต่คุณผ่าน a String) คุณสามารถดูที่นี่ว่ามีเพียงAddที่จะใช้เวลาObjectเป็นอาร์กิวเมนต์ที่สองคือการเลิกใช้
ทิม Schmelter

2
AddWithValueมีเพียงแค่การทำงานเดียวกันกว่าAddด้วยObjectแต่ก็ไม่ได้เป็นวิธีที่แนะนำ ทั้งสองจำเป็นต้องอนุมานประเภท
Tim Schmelter

2
คุณพูดถูกจริงๆ @TimSchmelter การอ่านข้อความของฉันมีข้อบกพร่อง ขอบคุณสำหรับการแก้ไข ฉันกำลังเขียนรหัสใหม่ที่ฉันจะใช้เพิ่ม () และฉันจะเปลี่ยน upvote ของฉันในคำตอบนี้เป็น downvote เนื่องจาก Rahul Nikate นั้นผิดพลาดเหมือนฉัน
TonyG

2
@TimSchmelter ขอบคุณสำหรับคำแนะนำของคุณ ฉันแก้ไขคำตอบของฉันแล้ว
ราหุล Nikate

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 ในหลากหลายรูปแบบ

กระบวนงานที่เก็บไว้เป็นวัตถุปฏิบัติการที่รวบรวมไว้ล่วงหน้าซึ่งมีคำสั่ง SQL หนึ่งรายการขึ้นไป ในหลายกรณีขั้นตอนการจัดเก็บยอมรับพารามิเตอร์ป้อนเข้าและส่งคืนค่าหลายค่า สามารถกำหนดค่าพารามิเตอร์ได้หากมีการเขียนโพรซีเดอร์ที่เก็บไว้เพื่อยอมรับค่าเหล่านั้น ตัวอย่างขั้นตอนการจัดเก็บด้วยการยอมรับพารามิเตอร์การป้อนข้อมูลได้รับด้านล่าง:

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

ขั้นตอนที่เก็บไว้ข้างต้นคือการยอมรับชื่อประเทศ (@COUNTRY VARCHAR (20)) เป็นพารามิเตอร์และส่งคืนผู้เผยแพร่ทั้งหมดจากประเทศที่ป้อน เมื่อ CommandType ถูกตั้งค่าเป็น StoredProcedure คุณสามารถใช้คอลเลกชันพารามิเตอร์เพื่อกำหนดพารามิเตอร์

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

คำตอบของคุณไม่ได้ใช้การใช้บล็อกซึ่งเป็นแนวปฏิบัติที่ดีที่สุด นอกจากนี้ควรมีบล็อกลองลองเพื่อจัดการกับข้อยกเว้นใด ๆ
ริป
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.