Comment exécuter une procédure stockée dans un programme C #


254

Je veux exécuter cette procédure stockée à partir d'un programme C #.

J'ai écrit la procédure stockée suivante dans une fenêtre de requête SqlServer et l'ai enregistrée en tant que 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

ÉDITÉ:

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

Cela affiche l'exception Cannot find the stored procedure dbo.test. Dois-je fournir le chemin d'accès? Si oui, à quel endroit les procédures stockées doivent-elles être stockées?


3
Il vaut mieux utiliser une base de données autre que master même pour les tests. Il s'agit d'une base de données système et vous causerez éventuellement des problèmes. Dans SQL 2012, il ne me permettra pas de créer une table là-bas. Cela me permettra à l'inverse de créer un sproc. : /
Joe Johnston

Nonobstant les réponses: avez-vous vérifié si votre sp a bien été créé avec le nom que vous avez donné (dbo.test)? Je ne sais pas ce qui se passerait si un utilisateur non-dbo essayait de créer dbo.test ... serait-il créé en tant que non-dbo.test?
DigCamara

5
@obayhan Cette question a été posée 2 ans avant celle dont vous prétendez qu'il s'agit d'un double possible. Veuillez, à l'avenir, marquer la question la plus récente comme étant en double.
RyanfaeScotland

Réponses:


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

51
Vous pouvez même vous débarrasser du conn.Close, est sous-entendu par leDispose
Remus Rusanu

16
C'est vrai pour ce cas. J'aime avoir des correspondances Openet des Closeappels. Si vous dites à l'avenir de refactoriser l'objet de connexion en tant que champ et de supprimer l'instruction using, vous pouvez accidentellement oublier d'ajouter Closeet de vous retrouver avec une connexion ouverte.
Mehrdad Afshari

11
Comment feriez-vous cela si le proc stocké avait besoin de paramètres? il suffit d'ajouter les paramètres à l'objet de commande avec les mêmes noms et types?
Dani

5
@Dani Oui. Ajoutez simplement les paramètres à la Parameterscollection de l' SqlCommandobjet.
Mehrdad Afshari

Pourrai-je envoyer l'option de valeur DROPDOWN dans le 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"]);
        }
    }
}

Voici quelques liens intéressants que vous pouvez lire:


32
Vous devriez vraiment utiliser le mot-clé "using". Poussez cette responsabilité ouverte / étroite au cadre.
TruMan1

1
Définition de SqlCommand: public sealed class SqlCommand : System.Data.Common.DbCommand, ICloneable, IDisposable. Le mettre en usingdéclaration aidera à nettoyer.
themefield

24

Procédure d'appel du magasin en 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();

}}

Je m'inquiète de la façon dont cmd.CommandText = "Stored1" interprète ma procédure stockée. Je ne sais pas.
Mignon

2
Le "CommandText" doit être défini sur le NOM de la procédure stockée, qui est ensuite exécutée à partir de C # comme si vous aviez exécuté "exec StoredProcedureName" dans SSMS - ou de quoi vous inquiétez-vous?
marc_s

Comment puis-je donner le nom de la procédure stockée pour la procédure stockée ci-dessus, pouvez-vous me le dire?
Mignon

donc, tout d'abord, vous devrez créer la procédure stockée, dans le cas du code que vous avez, vous devrez ajouter: "create procedure dbo.NameOfYourStoredProcedureHere as" au début
BlackTigerX

1
@Cute: si vous l'avez comme procédure stockée, vous DEVEZ avoir un nom! Nom utilisé dans l'appel "CREATE PROCEDURE (nom_procédure)". Si vous ne l'avez pas, vous n'avez pas de procédure stockée (mais juste un lot d'instructions T-SQL) et vous ne pouvez pas utiliser la "CommandType = StoredProcedure", évidemment
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

C'est le code pour exécuter des procédures stockées avec et sans paramètres via la réflexion. Notez que les noms des propriétés des objets doivent correspondre aux paramètres de la procédure stockée.

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

En utilisant 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

Vos lignes de commentaires sont cassées, même si vous pouvez donner une procédure stockée dans votre commentaire qui nous serait utile.
PeerNet

avez ajouté la procédure stockée dans le code, vérifiez-la.
Johnny

4

ceci est un exemple d'une procédure stockée qui renvoie une valeur et son exécution en 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

Utilisation de Dapper. j'ai donc ajouté ceci j'espère que quelqu'un vous aidera.

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

Veuillez consulter Crane (je suis l'auteur)

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

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

A également un tas d'autres fonctionnalités que vous pourriez aimer.


cela ne fonctionne pas. Est-ce obsolète? Je n'ai pas pu trouver la méthode Procédure.
Maddy

J'ai mis à jour l'exemple, merci de me le faire savoir.
Greg R Taylor

Comment renvoyer plusieurs jeux de données avec Crane? Mon proc stocké renvoie 3 jeux de données, et je ne suis intéressé que par le deuxième jeu de données. Mais Crane ne me rend que le premier.
Hoang Minh

1

Vous voulez dire que votre code est DDL? Si c'est le cas, MSSQL n'a aucune différence. Les exemples ci-dessus montrent bien comment l'invoquer. Assurez-vous simplement

CommandType = CommandType.Text

1

Aucune réponse Dapper ici. J'ai donc ajouté un

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);
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.