So führen Sie eine gespeicherte Prozedur im C # -Programm aus


254

Ich möchte diese gespeicherte Prozedur von einem C # -Programm ausführen.

Ich habe die folgende gespeicherte Prozedur in ein SqlServer-Abfragefenster geschrieben und als gespeichert1 gespeichert:

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

EDITIERT:

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

Dies zeigt die Ausnahme an Cannot find the stored procedure dbo.test. Muss ich den Pfad angeben? Wenn ja, an welchem ​​Ort sollen die gespeicherten Prozeduren gespeichert werden?


3
Sie sollten auch zum Testen eine andere Datenbank als den Master verwenden. Dies ist eine Systemdatenbank, und Sie werden schließlich Probleme verursachen. In SQL 2012 kann ich dort keine Tabelle erstellen. Umgekehrt kann ich einen Sproc erstellen. : /
Joe Johnston

Ungeachtet der Antworten: Haben Sie überprüft, ob Ihr SP tatsächlich mit dem von Ihnen angegebenen Namen erstellt wurde (dbo.test)? Ich weiß nicht, was passieren würde, wenn ein Nicht-Dbo-Benutzer versucht, dbo.test zu erstellen ... würde es als Nicht-dbo.test erstellt werden?
DigCamara

5
@obayhan Diese Frage wurde 2 Jahre vor der Frage gestellt, von der Sie behaupten, dass es sich um ein mögliches Duplikat handelt. Bitte markieren Sie in Zukunft die letzte Frage als Duplikat.
RyanfaeScotland

Antworten:


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

51
Sie können sogar die loswerden conn.Close, wird von derDispose
Remus Rusanu

16
Das gilt für diesen Fall. Ich habe gerne Matching Openund CloseAnrufe. Wenn Sie sagen, dass Sie das Verbindungsobjekt in Zukunft als Feld umgestalten und die using-Anweisung entfernen, vergessen Sie möglicherweise versehentlich, Closeeine offene Verbindung hinzuzufügen und zu erhalten.
Mehrdad Afshari

11
Wie würden Sie dies tun, wenn der gespeicherte Prozess Parameter benötigt? Fügen Sie dem Befehlsobjekt einfach die Parameter mit denselben Namen und Typen hinzu.
Dani

5
@Dani Ja. Fügen Sie einfach die Parameter zur ParametersSammlung des SqlCommandObjekts hinzu.
Mehrdad Afshari

Kann ich die DROPDOWN-Wertoption im SP senden?
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"]);
        }
    }
}

Hier sind einige interessante Links, die Sie lesen können:


32
Sie sollten wirklich das Schlüsselwort "using" verwenden. Übertragen Sie diese offene / geschlossene Verantwortung auf das Framework.
TruMan1

1
Definition von SqlCommand : public sealed class SqlCommand : System.Data.Common.DbCommand, ICloneable, IDisposable. Setzen Sie es in usingAussage hilft beim Aufräumen.
Themenfeld

24

Aufrufen der Speicherprozedur 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();

}}

Ich mache mir Sorgen darüber, wie cmd.CommandText = "Stored1" meine gespeicherte Prozedur interpretiert. Ich weiß es nicht.
Süß

2
Der "CommandText" muss auf den NAME der gespeicherten Prozedur gesetzt werden, die dann von C # ausgeführt wird, als hätten Sie "exec StoredProcedureName" in SSMS ausgeführt - oder worüber machen Sie sich Sorgen?
marc_s

Wie kann ich den Namen der gespeicherten Prozedur für die oben gespeicherte Prozedur angeben? Kannst du mir das bitte sagen?
Süß

Also müssten Sie zuerst die gespeicherte Prozedur erstellen, im Fall des Codes, den Sie haben, müssten Sie hinzufügen: "create procedure dbo.NameOfYourStoredProcedureHere as" am Anfang
BlackTigerX

1
@Cute: Wenn Sie dies als eine gespeicherte Prozedur haben, Sie muss einen Namen haben! Der Name, der im Aufruf "CREATE PROCEDURE (procedureurename)" verwendet wird. Wenn Sie das nicht haben, haben Sie keine gespeicherte Prozedur (sondern nur einen Stapel von T-SQL-Anweisungen) und können dann nicht "CommandType = StoredProcedure" verwenden, offensichtlich
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

Dies ist Code zum Ausführen gespeicherter Prozeduren mit und ohne Parameter über Reflektion. Beachten Sie, dass die Objekteigenschaftsnamen mit den Parametern der gespeicherten Prozedur übereinstimmen müssen.

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

Mit 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

Ihre Kommentarzeilen sind unterbrochen, auch wenn Sie in Ihrem Kommentar eine gespeicherte Prozedur angeben können, die für uns gut wäre.
PeerNet

Haben Sie die gespeicherte Prozedur im Code hinzugefügt, überprüfen Sie sie.
Johnny

4

Dies ist ein Beispiel für eine gespeicherte Prozedur, die einen Wert zurückgibt und in c # ausgeführt wird

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

Dapper verwenden. Also habe ich das hinzugefügt. Ich hoffe, jemand hilft.

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

Bitte schauen Sie sich Crane an (ich bin der Autor)

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

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

Hat auch eine Reihe anderer Funktionen, die Ihnen gefallen könnten.


Das funktioniert nicht. Ist das veraltet? Ich konnte die Methode Prozedur nicht finden.
Maddy

Ich habe das Beispiel aktualisiert, danke, dass Sie mich informiert haben.
Greg R Taylor

Wie können Sie mit Crane mehrere Datensätze zurückgeben? Mein gespeicherter Prozess gibt 3 Datensätze zurück und ich interessiere mich nur für den zweiten Datensatz. Aber Crane gibt mir nur den ersten zurück.
Hoang Minh

1

Sie meinen, Ihr Code ist DDL? Wenn ja, hat MSSQL keinen Unterschied. Die obigen Beispiele zeigen gut, wie man dies aufruft. Stellen Sie einfach sicher

CommandType = CommandType.Text

1

Keine adrette Antwort hier. Also habe ich einen hinzugefügt

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);
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.