Jak wykonać procedurę przechowywaną w programie C #

254

Chcę wykonać tę procedurę przechowywaną z programu w języku C #.

Napisałem następującą procedurę przechowywaną w oknie zapytania SqlServer i zapisałem ją jako przechowywaną1:

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

EDYTOWANE:

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

Wyświetla to wyjątek Cannot find the stored procedure dbo.test. Czy muszę podać ścieżkę? Jeśli tak, w jakim miejscu powinny być przechowywane procedury przechowywane?

Uroczy
źródło
3
Lepiej jest używać bazy danych innej niż master nawet do testowania. To jest systemowa baza danych i w końcu spowodujesz problemy. W SQL 2012 nie pozwoli mi tam utworzyć tabeli. Z drugiej strony pozwoli mi to stworzyć sproc. : /
Joe Johnston,
Niezależnie od odpowiedzi: czy sprawdziłeś, czy Twój sp został utworzony z podaną przez ciebie nazwą (dbo.test)? Nie wiem, co by się stało, gdyby użytkownik inny niż dbo próbował utworzyć plik dbo.test ... czy zostałby utworzony jako plik inny niż dbo.test?
DigCamara,
5
@obayhan To pytanie zostało zadane 2 lata przed tym, o którym twierdzisz, że jest możliwe powtórzenie. W przyszłości proszę zaznaczyć ostatnie pytanie jako duplikat.
RyanfaeScotland

Odpowiedzi:

333
using (var conn = new SqlConnection(connectionString))
using (var command = new SqlCommand("ProcedureName", conn) { 
                           CommandType = CommandType.StoredProcedure }) {
   conn.Open();
   command.ExecuteNonQuery();
}
Mehrdad Afshari
źródło
51
Możesz się go nawet pozbyć conn.Close, sugerujeDispose
Remus Rusanu,
16
To prawda w tym przypadku. Lubię mieć pasujące Openi Closepołączenia. Jeśli powiesz, refaktoryzuj obiekt połączenia jako pole w przyszłości i usuń instrukcję using, możesz przypadkowo zapomnieć dodać Closei zakończyć połączenie otwarte.
Mehrdad Afshari,
11
Jak byś to zrobił, gdyby przechowywane procedury wymagały parametrów? po prostu dodać parametry do obiektu polecenia o tych samych nazwach i typach?
Dani,
5
@Dani Tak. Wystarczy dodać parametry do Parameterskolekcji SqlCommandobiektu.
Mehrdad Afshari,
Czy będę mógł wysłać opcję wartości DROPDOWN w 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"]);
        }
    }
}

Oto kilka interesujących linków, które możesz przeczytać:

Bhaskar
źródło
32
Naprawdę powinieneś użyć słowa kluczowego „using”. Przekaż tę otwartą / bliską odpowiedzialność ramom.
TruMan1
1
Definicja SqlCommand: public sealed class SqlCommand : System.Data.Common.DbCommand, ICloneable, IDisposable. Umieszczenie go w usingoświadczeniu pomoże oczyścić.
tematyczny
24

Procedura wywoływania sklepu w 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();
Vaibhav Bhootna
źródło
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();

}}
BlackTigerX
źródło
Martwię się o to, jak cmd.CommandText = "Stored1" interpretuje moją procedurę przechowywaną. Nie wiem.
Śliczne
2
„CommandText” musi być ustawiony na NAZWĘ procedury przechowywanej, która jest następnie wykonywana z C #, tak jakbyś wykonał „exec StoredProcedureName” w SSMS - lub czym się martwisz?
marc_s,
Jak mogę podać nazwę procedury składowanej dla powyższej procedury składowanej, czy możesz mi powiedzieć?
Śliczne
więc najpierw musisz utworzyć procedurę składowaną, w przypadku kodu, który masz, musisz dodać: „utwórz procedurę dbo.NameOfYourStoredProcedureHere as” na początku
BlackTigerX
1
@Cute: jeśli masz to jako procedurę przechowywaną, MUSISZ mieć nazwę! Nazwa używana w wywołaniu „CREATE PROCEDURE (nazwa procedury”). Jeśli tego nie masz, to nie masz procedury składowanej (a tylko zestaw instrukcji T-SQL), a następnie nie możesz użyć „CommandType = StoredProcedure”, oczywiście
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"]);
}
ABC
źródło
14

Jest to kod do wykonywania procedur przechowywanych zi bez parametrów poprzez odbicie. Należy pamiętać, że nazwy właściwości obiektów muszą być zgodne z parametrami procedury składowanej.

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;

    }
Salim Proctor
źródło
5

Korzystając z 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
Jasio
źródło
Twoje wiersze komentarza są przerywane, również jeśli możesz podać procedurę zapisaną w komentarzu, która byłaby dla nas dobra.
PeerNet
dodałem procedurę przechowywaną w kodzie, sprawdź to.
Johnny
4

jest to przykład procedury składowanej, która zwraca wartość i jej wykonanie w 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); 
zakaria kasmi
źródło
2

Korzystanie z Dappera. więc dodałem to, mam nadzieję, że ktoś pomoże.

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();
        }
Md.Rezwan
źródło
2

Proszę sprawdzić Crane (jestem autorem)

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

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

Ma również wiele innych funkcji, które mogą ci się spodobać.

Greg R. Taylor
źródło
to nie działa. Czy to jest przestarzałe? Nie mogłem znaleźć metody Procedura.
Maddy
Zaktualizowałem przykład, dziękuję za informację.
Greg R. Taylor
Jak zwracasz wiele zestawów danych za pomocą Crane? Mój przechowywany proc zwraca 3 zestawy danych, a interesuje mnie tylko drugi zestaw danych. Ale Crane zwraca mi tylko ten pierwszy.
Hoang Minh,
1

Masz na myśli, że twój kod to DDL? Jeśli tak, MSSQL nie ma różnicy. Powyższe przykłady dobrze pokazują, jak to wywołać. Po prostu upewnij się

CommandType = CommandType.Text
Zroszony
źródło
1

Nie Wytworny odpowiedź tutaj. Więc dodałem jeden

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);
Shreevardhan
źródło