Gọi một thủ tục được lưu trữ với tham số trong c #


138

Tôi có thể thực hiện xóa, chèn và cập nhật trong chương trình của mình và tôi cố gắng thực hiện thao tác chèn bằng cách gọi một thủ tục được lưu trữ được tạo từ cơ sở dữ liệu của tôi.

Đây là một nút chèn tôi làm việc tốt.

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

Đây là bắt đầu của nút để gọi thủ tục có tên sp_Add_contactđể thêm một liên hệ. Hai tham số cho sp_Add_contact(@FirstName,@LastName). Tôi đã tìm kiếm trên google cho một số ví dụ tốt nhưng tôi thấy không có gì thú vị.

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
Chỉ cần thêm một chút thông tin - bạn không nên đặt tên cho các thủ tục được lưu trữ trong ứng dụng của mình với tiền tố sp_, như trên với sp_Add_contact. tiền tố sp_ là một quy ước đặt tên Proc được lưu trữ hệ thống, khi SQL nhìn thấy nó, sẽ tìm kiếm thông qua tất cả các thủ tục được lưu trữ hệ thống trước khi có bất kỳ ứng dụng hoặc không gian lưu trữ nào của người dùng. Về vấn đề hiệu năng, nếu bạn quan tâm đến điều đó trong ứng dụng của mình, tiền tố sp_ sẽ làm giảm thời gian phản hồi của bạn.
Robert Achmann

Câu trả lời:


265

Nó khá giống với việc chạy truy vấn. Trong mã gốc của bạn, bạn đang tạo một đối tượng lệnh, đặt nó vào cmdbiến và không bao giờ sử dụng nó. Ở đây, tuy nhiên, bạn sẽ sử dụng nó thay vì da.InsertCommand.

Ngoài ra, sử dụng một usingcho tất cả các đối tượng dùng một lần, để bạn chắc chắn rằng chúng được xử lý đúng cách:

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
nhưng nếu thủ tục này trả về dữ liệu, làm thế nào tôi có thể bắt được nó trong C #?
MA9H

8
@ M009: Sau đó, bạn sử dụng ExecuteReaderhoặc ExecuteScalargọi nó.
Guffa

2
@ M009: Vâng, đó là một cách khác để làm điều tương tự. Bộ điều hợp dữ liệu sử dụng ExecuteReader.
Guffa

1
@DylanChen: Điều đó phụ thuộc vào cài đặt cơ sở dữ liệu. Cài đặt mặc định là các định danh không phân biệt chữ hoa chữ thường.
Guffa

1
@DylanChen: Đây là cài đặt đối chiếu của cơ sở dữ liệu để xác định xem các định danh có phân biệt chữ hoa chữ thường hay không.
Guffa

36

Bạn phải thêm các tham số vì SP cần thiết để thực thi

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 là một ý tưởng tồi; SQL Server không phải lúc nào cũng sử dụng độ dài chính xác cho nvarchar hoặc varchar, khiến chuyển đổi ngầm xảy ra. Tốt hơn là chỉ định rõ ràng độ dài của tham số, sau đó thêm giá trị riêng bằng cách sử dụng parameter.Value = txtfirstname.
George Stocker

14

cmd.Parameters.Add(String parameterName, Object value)bây giờ không được dùng nữa Thay vào đó hãy sử dụngcmd.Parameters.AddWithValue(String parameterName, Object value)

Thêm (Chuỗi tham số, giá trị đối tượng) đã không được chấp nhận. Sử dụng AddWithValue (Chuỗi tham số, giá trị đối tượng)

Không có sự khác biệt về chức năng. Lý do họ cmd.Parameters.Add(String parameterName, Object value)từ chối ủng hộ AddWithValue(String parameterName, Object value)là để làm rõ hơn. Đây là tài liệu tham khảo MSDN cho cùng

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
Bạn có một liên kết hoặc nguồn để khiếu nại cmd.Parameters.Addbị phản đối?
David

7
@TonyG: điều đó không đúng, câu trả lời được chấp nhận sử dụng mức quá tải ưa thích Addcũng không được phản đối. AddWithValuecũng không phải là cách tốt nhất vì nó xâm nhập vào loại tham số từ giá trị paramater. Điều này thường dẫn đến kế hoạch thực hiện xấu hoặc chuyển đổi không chính xác. Nó cũng không xác nhận tham số ở vị trí đầu tiên (loại nếu nếu Datetimebạn vượt qua a String). Bạn có thể thấy ở đây chỉ Addcó một Objectđối số thứ hai là không được chấp nhận.
Tim Schmelter

2
AddWithValuecó cùng chức năng so Addvới Object, nhưng nó không phải là cách ưa thích. Cả hai cần suy ra loại.
Tim Schmelter

2
Bạn hoàn toàn đúng, @TimSchmelter. Đọc văn bản của tôi là thiếu sót. Cảm ơn vì sự đúng đắn của bạn. Tôi đang viết một số mã mới trong đó tôi sẽ sử dụng Add (). Và tôi sẽ thay đổi upvote của mình trên Câu trả lời này thành downvote, vì Rahul Nikate cũng bị nhầm như tôi.
TonyG

2
@TimSchmelter Cảm ơn bạn đã tư vấn. Tôi đã chỉnh sửa câu trả lời của mình.
Rahul Nikate

3

Thay vào đó, tôi có một thư viện giúp dễ dàng làm việc với các 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

Các nhà cung cấp dữ liệu .NET bao gồm một số lớp được sử dụng để kết nối với nguồn dữ liệu, thực thi các lệnh và trả về các bản ghi. Đối tượng lệnh trong ADO.NET cung cấp một số phương thức Thực thi có thể được sử dụng để thực hiện các truy vấn SQL trong nhiều kiểu thời trang khác nhau.

Một thủ tục được lưu trữ là một đối tượng thực thi được biên dịch sẵn có chứa một hoặc nhiều câu lệnh SQL. Trong nhiều trường hợp, các thủ tục được lưu trữ chấp nhận các tham số đầu vào và trả về nhiều giá trị. Các giá trị tham số có thể được cung cấp nếu một thủ tục được lưu trữ được viết để chấp nhận chúng. Một thủ tục lưu trữ mẫu với chấp nhận tham số đầu vào được đưa ra dưới đây:

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

Quy trình được lưu trữ ở trên chấp nhận tên quốc gia (@COUNTRY VARCHAR (20)) làm tham số và trả về tất cả các nhà xuất bản từ quốc gia đầu vào. Khi CommandType được đặt thành StoredProcedure, bạn có thể sử dụng bộ sưu tập Tham số để xác định tham số.

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

Đoạn mã trên chuyển tham số quốc gia sang thủ tục được lưu trữ từ ứng dụng 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();
        }
    }
}

Câu trả lời của bạn không sử dụng các khối đó là cách thực hành tốt nhất. Ngoài ra, nên có một khối thử bắt để đối phó với bất kỳ trường hợp ngoại lệ.
Đã xem
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.