Come eseguire una procedura memorizzata all'interno del programma C #


254

Voglio eseguire questa procedura memorizzata da un programma C #.

Ho scritto la seguente procedura memorizzata in una finestra di query SqlServer e l'ho salvata come stored1:

use master 
go
create procedure dbo.test as

DECLARE @command as varchar(1000), @i int
SET @i = 0
WHILE @i < 5
BEGIN
Print 'I VALUE ' +CONVERT(varchar(20),@i)
EXEC(@command)
SET @i = @i + 1
END

MODIFICATO:

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
namespace AutomationApp
{
    class Program
    {
        public void RunStoredProc()
        {
            SqlConnection conn = null;
            SqlDataReader rdr  = null;

            Console.WriteLine("\nTop 10 Most Expensive Products:\n");

            try
            {
                conn = new SqlConnection("Server=(local);DataBase=master;Integrated Security=SSPI");
                conn.Open();
                SqlCommand cmd = new SqlCommand("dbo.test", conn);
                cmd.CommandType = CommandType.StoredProcedure;
                rdr = cmd.ExecuteReader();
                /*while (rdr.Read())
                {
                    Console.WriteLine(
                        "Product: {0,-25} Price: ${1,6:####.00}",
                        rdr["TenMostExpensiveProducts"],
                        rdr["UnitPrice"]);
                }*/
            }
            finally
            {
                if (conn != null)
                {
                    conn.Close();
                }
                if (rdr != null)
                {
                    rdr.Close();
                }
            }
        }
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World");
            Program p= new Program();
            p.RunStoredProc();      
            Console.Read();
        }
    }
}

Questo mostra l'eccezione Cannot find the stored procedure dbo.test. Devo fornire il percorso? In caso affermativo, in quale posizione devono essere archiviate le procedure memorizzate?


3
È meglio utilizzare un database diverso da master anche per i test. Questo è un database di sistema e alla fine causerai problemi. In SQL 2012 non mi consente di creare una tabella lì. Al contrario, mi permetterà di creare uno sproc. : /
Joe Johnston il

Nonostante le risposte: hai verificato se il tuo SP è stato effettivamente creato con il nome che hai dato (dbo.test)? Non so cosa succederebbe se un utente non dbo provasse a creare dbo.test ... sarebbe creato come non-dbo.test?
DigCamara,

5
@obayhan Questa domanda è stata posta 2 anni prima di quella di cui si afferma che è un possibile duplicato. In futuro, contrassegnare la domanda più recente come duplicata.
Ryanfae Scozia,

Risposte:


333
using (var conn = new SqlConnection(connectionString))
using (var command = new SqlCommand("ProcedureName", conn) { 
                           CommandType = CommandType.StoredProcedure }) {
   conn.Open();
   command.ExecuteNonQuery();
}

51
Puoi anche sbarazzarti del conn.Close, è implicito nelDispose
Remus Rusanu il

16
Questo è vero per questo caso. Mi piace avere abbinamenti Opene Closechiamate. Se dite, rifattate l'oggetto connessione come campo in futuro e rimuovete l'istruzione using, potreste accidentalmente dimenticare di aggiungere Closee finire con una connessione aperta.
Mehrdad Afshari,

11
Come faresti se il proc memorizzato avesse bisogno di parametri? basta aggiungere i parametri all'oggetto comando con gli stessi nomi e tipi?
Dani,

5
@Dani Sì. Basta aggiungere i parametri alla Parametersraccolta SqlCommanddell'oggetto.
Mehrdad Afshari,

Potrò inviare l'opzione del valore DROPDOWN in SP?
SearchForKnowledge,

246
using (SqlConnection conn = new SqlConnection("Server=(local);DataBase=Northwind;Integrated Security=SSPI")) {
    conn.Open();

    // 1.  create a command object identifying the stored procedure
    SqlCommand cmd  = new SqlCommand("CustOrderHist", conn);

    // 2. set the command object so it knows to execute a stored procedure
    cmd.CommandType = CommandType.StoredProcedure;

    // 3. add parameter to command, which will be passed to the stored procedure
    cmd.Parameters.Add(new SqlParameter("@CustomerID", custId));

    // execute the command
    using (SqlDataReader rdr = cmd.ExecuteReader()) {
        // iterate through results, printing each to console
        while (rdr.Read())
        {
            Console.WriteLine("Product: {0,-35} Total: {1,2}",rdr["ProductName"],rdr["Total"]);
        }
    }
}

Ecco alcuni link interessanti che potresti leggere:


32
Dovresti davvero usare la parola chiave "using". Spingere quella responsabilità aperta / chiusa al framework.
TruMan1

1
Definizione di SqlCommand: public sealed class SqlCommand : System.Data.Common.DbCommand, ICloneable, IDisposable. Mettilo nella usingdichiarazione aiuterà a ripulire.
themefield,

24

Chiamata alla procedura di archiviazione in C #

    SqlCommand cmd = new SqlCommand("StoreProcedureName",con);
    cmd.CommandType=CommandType.StoredProcedure;
    cmd.Parameters.AddWithValue("@value",txtValue.Text);
    con.Open();
    int rowAffected=cmd.ExecuteNonQuery();
    con.Close();

21
using (SqlConnection sqlConnection1 = new SqlConnection("Your Connection String")) {
using (SqlCommand cmd = new SqlCommand()) {
  Int32 rowsAffected;

  cmd.CommandText = "StoredProcedureName";
  cmd.CommandType = CommandType.StoredProcedure;
  cmd.Connection = sqlConnection1;

  sqlConnection1.Open();

  rowsAffected = cmd.ExecuteNonQuery();

}}

Sono preoccupato per come cmd.CommandText = "Stored1" interpreta la mia procedura memorizzata. Non lo so.
Carino

2
"CommandText" deve essere impostato sul NAME della procedura memorizzata, che viene quindi eseguita da C # come se fosse stato eseguito "exec StoredProcedureName" in SSMS - o di cosa ti preoccupi?
marc_s

Come posso indicare il nome della procedura memorizzata per la procedura memorizzata sopra?
Carino

quindi, prima, dovresti creare la procedura memorizzata, nel caso del codice che hai, devi aggiungere: "crea procedura dbo.NameOfYourStoredProcedureHere come" all'inizio
BlackTigerX

1
@Cute: se lo hai come procedura memorizzata, DEVI avere un nome! Il nome utilizzato nella chiamata "CREATE PROCEDURE (nome procedur)". Se non lo possiedi, non hai una procedura memorizzata (ma solo un batch di istruzioni T-SQL) e quindi non puoi utilizzare "CommandType = StoredProcedure", ovviamente
marc_s

15
SqlConnection conn = null;
SqlDataReader rdr  = null;
conn = new SqlConnection("Server=(local);DataBase=Northwind;Integrated Security=SSPI");
conn.Open();

// 1.  create a command object identifying
//     the stored procedure
SqlCommand cmd  = new SqlCommand("CustOrderHist", conn);

// 2. set the command object so it knows
//    to execute a stored procedure
cmd.CommandType = CommandType.StoredProcedure;

// 3. add parameter to command, which
//    will be passed to the stored procedure
cmd.Parameters.Add(new SqlParameter("@CustomerID", custId));

// execute the command
rdr = cmd.ExecuteReader();

// iterate through results, printing each to console
while (rdr.Read())
{
    Console.WriteLine("Product: {0,-35} Total: {1,2}", rdr["ProductName"], rdr["Total"]);
}

14

Questo è il codice per l'esecuzione di stored procedure con e senza parametri tramite reflection. Si noti che i nomi delle proprietà degli oggetti devono corrispondere ai parametri della procedura memorizzata.

private static string ConnString = ConfigurationManager.ConnectionStrings["SqlConnection"].ConnectionString;
    private SqlConnection Conn = new SqlConnection(ConnString);

    public void ExecuteStoredProcedure(string procedureName)
    {
        SqlConnection sqlConnObj = new SqlConnection(ConnString);

        SqlCommand sqlCmd = new SqlCommand(procedureName, sqlConnObj);
        sqlCmd.CommandType = CommandType.StoredProcedure;

        sqlConnObj.Open();
        sqlCmd.ExecuteNonQuery();
        sqlConnObj.Close();
    }

    public void ExecuteStoredProcedure(string procedureName, object model)
    {
        var parameters = GenerateSQLParameters(model);
        SqlConnection sqlConnObj = new SqlConnection(ConnString);

        SqlCommand sqlCmd = new SqlCommand(procedureName, sqlConnObj);
        sqlCmd.CommandType = CommandType.StoredProcedure;

        foreach (var param in parameters)
        {
            sqlCmd.Parameters.Add(param);
        }

        sqlConnObj.Open();
        sqlCmd.ExecuteNonQuery();
        sqlConnObj.Close();
    }

    private List<SqlParameter> GenerateSQLParameters(object model)
    {
        var paramList = new List<SqlParameter>();
        Type modelType = model.GetType();
        var properties = modelType.GetProperties();
        foreach (var property in properties)
        {
            if (property.GetValue(model) == null)
            {
                paramList.Add(new SqlParameter(property.Name, DBNull.Value));
            }
            else
            {
                paramList.Add(new SqlParameter(property.Name, property.GetValue(model)));
            }
        }
        return paramList;

    }

5

Utilizzando Ado.net

using System;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;

namespace PBDataAccess
{
    public class AddContact
    {   
        // for preparing connection to sql server database   

        private SqlConnection conn; 

        // for preparing sql statement or stored procedure that 
        // we want to execute on database server

        private SqlCommand cmd; 

        // used for storing the result in datatable, basically 
        // dataset is collection of datatable

        private DataSet ds; 

        // datatable just for storing single table

        private DataTable dt; 

        // data adapter we use it to manage the flow of data
        // from sql server to dataset and after fill the data 
        // inside dataset using fill() method   

        private SqlDataAdapter da; 


        // created a method, which will return the dataset

        public DataSet GetAllContactType() 
        {



    // retrieving the connection string from web.config, which will 
    // tell where our database is located and on which database we want
    // to perform opearation, in this case we are working on stored 
    // procedure so you might have created it somewhere in your database. 
    // connection string will include the name of the datasource, your 
    // database name, user name and password.

        using (conn = new SqlConnection(ConfigurationManager.ConnectionString["conn"]
        .ConnectionString)) 

                {
                    // Addcontact is the name of the stored procedure
                    using (cmd = new SqlCommand("Addcontact", conn)) 

                    {
                        cmd.CommandType = CommandType.StoredProcedure;

                    // here we are passing the parameters that 
                    // Addcontact stored procedure expect.
                     cmd.Parameters.Add("@CommandType",
                     SqlDbType.VarChar, 50).Value = "GetAllContactType"; 

                        // here created the instance of SqlDataAdapter
                        // class and passed cmd object in it
                        da = new SqlDataAdapter(cmd); 

                        // created the dataset object
                        ds = new DataSet(); 

                        // fill the dataset and your result will be
                        stored in dataset
                        da.Fill(ds); 
                    }                    
            }  
            return ds;
        }
}

****** Stored Procedure ******

CREATE PROCEDURE Addcontact
@CommandType VARCHAR(MAX) = NULL
AS
BEGIN
  IF (@CommandType = 'GetAllContactType')
  BEGIN
    SELECT * FROM Contacts
  END
END

Le tue righe di commento sono interrotte, anche se puoi inserire una procedura memorizzata nel tuo commento che andrebbe bene per noi.
PeerNet,

ha aggiunto la procedura memorizzata nel codice, verificala.
Johnny,

4

questo è un esempio di una procedura memorizzata che restituisce un valore e la sua esecuzione in c #

CREATE PROCEDURE [dbo].[InsertPerson]   
-- Add the parameters for the stored procedure here  
@FirstName nvarchar(50),@LastName nvarchar(50),  
@PersonID int output  
AS  
BEGIN  
    insert [dbo].[Person](LastName,FirstName) Values(@LastName,@FirstName)  

    set @PersonID=SCOPE_IDENTITY()  
END  
Go  


--------------
 // Using stored procedure in adapter to insert new rows and update the identity value.  
   static void InsertPersonInAdapter(String connectionString, String firstName, String lastName) {  
      String commandText = "dbo.InsertPerson";  
      using (SqlConnection conn = new SqlConnection(connectionString)) {  
         SqlDataAdapter mySchool = new SqlDataAdapter("Select PersonID,FirstName,LastName from [dbo].[Person]", conn);  

         mySchool.InsertCommand = new SqlCommand(commandText, conn);  
         mySchool.InsertCommand.CommandType = CommandType.StoredProcedure;  

         mySchool.InsertCommand.Parameters.Add(  
             new SqlParameter("@FirstName", SqlDbType.NVarChar, 50, "FirstName"));  
         mySchool.InsertCommand.Parameters.Add(  
             new SqlParameter("@LastName", SqlDbType.NVarChar, 50, "LastName"));  

         SqlParameter personId = mySchool.InsertCommand.Parameters.Add(new SqlParameter("@PersonID", SqlDbType.Int, 0, "PersonID"));  
         personId.Direction = ParameterDirection.Output;  

         DataTable persons = new DataTable();  
         mySchool.Fill(persons);  

         DataRow newPerson = persons.NewRow();  
         newPerson["FirstName"] = firstName;  
         newPerson["LastName"] = lastName;  
         persons.Rows.Add(newPerson);  

         mySchool.Update(persons);  
         Console.WriteLine("Show all persons:");  
         ShowDataTable(persons, 14); 

2

Usando Dapper. così ho aggiunto questo spero che qualcuno aiuti.

public void Insert(ProductName obj)
        {
            SqlConnection connection = new SqlConnection(Connection.GetConnectionString());
            connection.Open();
            connection.Execute("ProductName_sp", new
            { @Name = obj.Name, @Code = obj.Code, @CategoryId = obj.CategoryId, @CompanyId = obj.CompanyId, @ReorderLebel = obj.ReorderLebel, @logo = obj.logo,@Status=obj.Status, @ProductPrice = obj.ProductPrice,
                @SellingPrice = obj.SellingPrice, @VatPercent = obj.VatPercent, @Description=obj.Description, @ColourId = obj.ColourId, @SizeId = obj.SizeId,
                @BrandId = obj.BrandId, @DisCountPercent = obj.DisCountPercent, @CreateById =obj.CreateById, @StatementType = "Create" }, commandType: CommandType.StoredProcedure);
            connection.Close();
        }

2

Dai un'occhiata a Crane (sono l'autore)

https://www.nuget.org/packages/Crane/

SqlServerAccess sqlAccess = new SqlServerAccess("your connection string");
var result = sqlAccess.Command().ExecuteNonQuery("StoredProcedureName");

Ha anche un sacco di altre funzionalità che potrebbero piacerti.


questo non funziona. È obsoleto? Non sono riuscito a trovare il metodo Procedura.
Maddy,

Ho aggiornato l'esempio, grazie per avermelo fatto notare.
Greg R Taylor,

Come si restituiscono più set di dati con Crane? Il mio proc memorizzato restituisce 3 set di dati e sono interessato solo al secondo set di dati. Ma Crane mi restituisce solo il primo.
Hoang Minh,

1

Vuoi dire che il tuo codice è DDL? In tal caso, MSSQL non ha alcuna differenza. Gli esempi sopra mostrano bene come invocare questo. Assicurati e basta

CommandType = CommandType.Text

1

Nessuna risposta Dapper qui. Quindi ne ho aggiunto uno

using Dapper;
using System.Data.SqlClient;

using (var cn = new SqlConnection(@"Server=(local);DataBase=master;Integrated Security=SSPI"))
    cn.Execute("dbo.test", commandType: CommandType.StoredProcedure);
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.