Como executar um procedimento armazenado no programa C #

254

Eu quero executar este procedimento armazenado de um programa C #.

Eu escrevi o seguinte procedimento armazenado em uma janela de consulta do SqlServer e o salvei como armazenado1:

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

EDITADO:

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

Isso exibe a exceção Cannot find the stored procedure dbo.test. Preciso fornecer o caminho? Se sim, em que local os procedimentos armazenados devem ser armazenados?

Fofa
fonte
3
É melhor usar um banco de dados que não seja o mestre, mesmo para testes. Este é um banco de dados do sistema e você causará problemas eventualmente. No SQL 2012, não me permite criar uma tabela lá. Por outro lado, permitirá que eu crie um sproc. : /
Joe Johnston
Não obstante as respostas: você verificou se seu sp foi realmente criado com o nome que você deu (dbo.test)? Não sei o que aconteceria se um usuário não-dbo tentasse criar o dbo.test ... seria criado como não-dbo.test?
21413 DigCamara
5
@obayhan Esta pergunta foi feita 2 anos antes da que você afirma ser uma possível duplicata. No futuro, marque a pergunta mais recente como duplicada.
RyanfaeScotland

Respostas:

333
using (var conn = new SqlConnection(connectionString))
using (var command = new SqlCommand("ProcedureName", conn) { 
                           CommandType = CommandType.StoredProcedure }) {
   conn.Open();
   command.ExecuteNonQuery();
}
Mehrdad Afshari
fonte
51
Você pode até se livrar do conn.Close, está implícito naDispose
Remus Rusanu
16
Isso é verdade para este caso. Eu gosto de ter correspondência Opene Closechamadas. Se você disser, refatorar o objeto de conexão como um campo no futuro e remover a instrução using, você pode acidentalmente esquecer de adicionar Closee terminar com uma conexão aberta.
Mehrdad Afshari
11
Como você faria isso se o processo armazenado precisasse de parâmetros? basta adicionar os parâmetros ao objeto de comando com os mesmos nomes e tipos?
21711 Dani
5
@Dani Yes. Basta adicionar os parâmetros à Parameterscoleção do SqlCommandobjeto.
Mehrdad Afshari
Posso enviar a opção de valor DROPDOWN no ​​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"]);
        }
    }
}

Aqui estão alguns links interessantes que você pode ler:

Bhaskar
fonte
32
Você realmente deve usar a palavra-chave "using". Empurre essa responsabilidade de abrir / fechar para a estrutura.
TruMan1
1
Definição de SqlCommand: public sealed class SqlCommand : System.Data.Common.DbCommand, ICloneable, IDisposable. Colocá-lo em usingdeclaração ajudará na limpeza.
themefield
24

Chamando o procedimento de armazenamento em 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
fonte
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
fonte
Estou preocupado com a forma como o cmd.CommandText = "Stored1" interpreta meu procedimento armazenado. Não sei.
bonito
2
O "CommandText" deve ser definido como o NOME do procedimento armazenado, que é então executado a partir do C # como se você tivesse executado "exec StoredProcedureName" no SSMS - ou com o que você está preocupado?
11289 marc_s
Como posso dar o nome do procedimento armazenado para o procedimento armazenado acima, você pode me dizer?
bonito
por isso, em primeiro lugar, você teria que criar o procedimento armazenado, no caso do código que você tem, você precisa adicionar: "criar procedimento dbo.NameOfYourStoredProcedureHere como" no início
BlackTigerX
1
@ Cute: se você tiver isso como um procedimento armazenado, DEVE ter um nome! O nome usado na chamada "CREATE PROCEDURE (procedurename)". Se você não tem isso, então você não tem um procedimento armazenado (mas apenas um lote de instruções T-SQL) e, em seguida, você não pode usar o "CommandType = StoredProcedure", obviusly
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
fonte
14

Este é um código para executar procedimentos armazenados com e sem parâmetros via reflexão. Observe que os nomes de propriedade dos objetos precisam corresponder aos parâmetros do procedimento armazenado.

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
fonte
5

Usando 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
Johnny
fonte
Suas linhas de comentário estão quebradas, também se você puder fornecer um procedimento armazenado em seu comentário que seria bom para nós.
PeerNet
tiver adicionado o procedimento armazenado no código, confira.
Johnny
4

este é um exemplo de um procedimento armazenado que retorna um valor e é executado em 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
fonte
2

Usando Dapper. então eu adicionei isso espero que alguém ajude.

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
fonte
2

Por favor, verifique Crane (eu sou o autor)

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

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

Também possui vários outros recursos que você pode gostar.

Greg R Taylor
fonte
isso não funciona. Isso está desatualizado? Não foi possível encontrar o método Procedimento.
Maddy
Atualizei o exemplo, obrigado por me informar.
Greg R Taylor
Como você retorna vários conjuntos de dados com o Crane? Meu proc armazenado retorna 3 conjuntos de dados e só estou interessado no segundo conjunto de dados. Mas Crane só me devolve o primeiro.
Hoang Minh
1

Você quer dizer que seu código é DDL? Nesse caso, o MSSQL não tem diferença. Os exemplos acima mostram bem como invocar isso. Apenas garanta

CommandType = CommandType.Text
Dewfy
fonte
1

Nenhuma resposta Dapper aqui. Então eu adicionei um

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
fonte