Chiamare una procedura memorizzata con parametro in c #


138

Posso fare una cancellazione, inserire e aggiornare nel mio programma e provo a fare un inserimento chiamando una procedura memorizzata creata dal mio database.

Questo un inserto di pulsante lo faccio funzionare bene.

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

Questo è l'inizio del pulsante per chiamare la procedura denominata sp_Add_contactper aggiungere un contatto. I due parametri per sp_Add_contact(@FirstName,@LastName). Ho cercato su Google qualche buon esempio ma non ho trovato nulla di interessante.

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
Solo un po 'di informazioni in più - non dovresti nominare le procedure memorizzate della tua applicazione con un prefisso sp_, come sopra con sp_Add_contact. il prefisso sp_ è una convenzione di denominazione dei processi memorizzata nel sistema che, quando SQL lo vede, cercherà tutte le procedure memorizzate nel sistema prima di qualsiasi proc memorizzato nello spazio utente o applicazione. Per quanto riguarda le prestazioni, se ti interessa ciò nella tua applicazione, il prefisso sp_ degraderà i tempi di risposta.
Robert Achmann,

Risposte:


265

È praticamente lo stesso di eseguire una query. Nel tuo codice originale stai creando un oggetto comando, inserendolo nella cmdvariabile e non lo usi mai. Qui, invece, lo userete invece di da.InsertCommand.

Inoltre, usa a usingper tutti gli oggetti usa e getta, in modo da essere sicuro che siano disposti correttamente:

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
ma se questa procedura restituisce dati, come posso catturarli in C #?
MA9H,

8
@ M009: Quindi si utilizza ExecuteReadero ExecuteScalarper chiamarlo.
Guffa,

2
@ M009: Sì, è un altro modo di fare la stessa cosa. L'adattatore dati utilizza ExecuteReader.
Guffa,

1
@DylanChen: dipende dalle impostazioni del database. L'impostazione predefinita è che gli identificatori non fanno distinzione tra maiuscole e minuscole.
Guffa,

1
@DylanChen: è l'impostazione di confronto del database che determina se gli identificatori sono sensibili al maiuscolo / minuscolo.
Guffa,

36

È necessario aggiungere parametri poiché è necessario per l'esecuzione dell'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 è una cattiva idea; SQL Server non utilizza sempre la lunghezza corretta per nvarchar o varchar, causando una conversione implicita. È meglio specificare la lunghezza del parametro in modo esplicito, quindi aggiungere il valore separatamente utilizzando parameter.Value = txtfirstname.
George Stocker,

14

cmd.Parameters.Add(String parameterName, Object value)è deprecato ora. Invece usacmd.Parameters.AddWithValue(String parameterName, Object value)

Aggiungi (String parameterName, Valore oggetto) è stato deprecato. Usa AddWithValue (String parameterName, Valore oggetto)

Non c'è differenza in termini di funzionalità. Il motivo per cui il deprecato cmd.Parameters.Add(String parameterName, Object value)a favore della AddWithValue(String parameterName, Object value)è quello di dare maggiore chiarezza. Ecco il riferimento MSDN per lo stesso

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
Hai un link o una fonte per il reclamo che cmd.Parameters.Addè obsoleto?
David,

7
@TonyG: non è vero, la risposta accettata utilizza il sovraccarico preferito di Addcui non è deprecato. AddWithValueInoltre, non è il modo migliore poiché deduce il tipo di parametro dal valore del parametro. Ciò porta spesso a piani di esecuzione errati o conversioni errate. Inoltre, non convalida il parametro in primo luogo (tipo fe se Datetimesi passa a String). Si può vedere qui che solo Addche prende un Objectè deprecato come secondo argomento.
Tim Schmelter,

2
AddWithValueha la stessa funzionalità rispetto a Addcon Object, ma non è il modo preferito. Entrambi devono dedurre il tipo.
Tim Schmelter,

2
Hai assolutamente ragione, @TimSchmelter. La mia lettura del testo era imperfetta. Grazie per la correzione. Sto scrivendo un nuovo codice in cui userò Add (). E cambierò il mio voto su questa risposta in un voto negativo, dato che Rahul Nikate si è sbagliato tanto quanto me.
TonyG,

2
@TimSchmelter Grazie per il tuo consiglio. Ho modificato la mia risposta.
Rahul Nikate,

3

In alternativa, ho una libreria che semplifica il lavoro con 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

I provider di dati .NET sono costituiti da un numero di classi utilizzate per connettersi a un'origine dati, eseguire comandi e restituire recordset. L'oggetto comando in ADO.NET fornisce una serie di metodi Execute che possono essere utilizzati per eseguire le query SQL in una varietà di mode.

Una procedura memorizzata è un oggetto eseguibile precompilato che contiene una o più istruzioni SQL. In molti casi le stored procedure accettano parametri di input e restituiscono più valori. I valori dei parametri possono essere forniti se viene scritta una procedura memorizzata per accettarli. Di seguito è riportata una procedura memorizzata di esempio con l'accettazione del parametro di input:

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

La procedura memorizzata sopra accetta un nome di paese (@COUNTRY VARCHAR (20)) come parametro e restituisce tutti i publisher dal paese di input. Dopo aver impostato CommandType su StoredProcedure, è possibile utilizzare la raccolta Parametri per definire i parametri.

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

Il codice sopra passa il parametro del paese alla procedura memorizzata dall'applicazione 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();
        }
    }
}

La tua risposta non utilizza i blocchi, che è una buona pratica. Inoltre, dovrebbe esserci un tentativo di catch block per gestire eventuali eccezioni.
Trisped
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.