Виклик збереженої процедури з параметром в 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_ - це система, що зберігається в системі конвенції про іменування, яка, коли SQL це бачить, спочатку здійснює пошук усіх системних процедур, що зберігаються, перед тим, як будь-який додаток або користувальницький простір, що зберігається. Що стосується продуктивності, якщо ви дбаєте про це у вашій програмі, префікс sp_ погіршить час вашої відповіді.
Роберт Ахман

Відповіді:


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.
Гуффа

1
@DylanChen: Це залежить від налаштувань бази даних. Настройка за замовчуванням полягає в тому, що ідентифікатори не відповідають обліку регістру.
Гуффа

1
@DylanChen: Це налаштування зібрання бази даних визначає, чи визначають ідентифікатори регістри.
Гуффа

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.
Джордж Стокер

14

cmd.Parameters.Add(String parameterName, Object value)зараз застаріло. Замість використанняcmd.Parameters.AddWithValue(String parameterName, Object value)

Додати (Параметр StringName, значення Object) застаріло. Використовуйте AddWithValue (String parameterName, Value Object)

Немає різниці в функціональності. Причина, через яку вони знехтували на 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застарілої претензії ?
Девід

7
@TonyG: це неправда, прийнята відповідь використовує бажану перевантаження, Addяка також не застаріла. AddWithValueтакож не найкращий спосіб, оскільки він виводить тип параметра зі значення параметра. Це часто призводить до поганих планів виконання або неправильних перетворень. Він також не перевіряє параметр в першу чергу (тип fe, якщо Datetimeви передаєте a String). Ви можете побачити тут , що тільки , Addякий приймає в Objectякості другого аргументу є застарілим.
Тім Шмелтер

2
AddWithValueмає такий же функціонал, що Addі для Object, але це не найкращий спосіб. Обидва повинні зробити висновок про тип.
Тім Шмелтер

2
Ви абсолютно праві, @TimSchmelter. Моє читання тексту було хибним. Дякуємо за виправлення. Я пишу новий код, де я буду використовувати Add (). І я зміню свою позицію щодо цієї відповіді на голосування, оскільки Рахул Нікате так само помилявся, як і я.
TonyG

2
@TimSchmelter Дякую за пораду. Я відредагував свою відповідь.
Рахул Нікате

3

Як альтернатива, у мене є бібліотека, яка полегшує роботу з документами: 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 надає ряд методів Execute, які можуть використовуватися для виконання 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();
        }
    }
}

Ваш відповідь не використовує з допомогою блоків , який є передовою практикою. Крім того, має бути блок "спробувати вловлювання" для вирішення будь-яких винятків.
Trisped
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.