Abgabeparameterwert in ADO.NET abrufen

96

Meine gespeicherte Prozedur hat einen Ausgabeparameter:

@ID INT OUT

Wie kann ich dies mit ado.net abrufen?

using (SqlConnection conn = new SqlConnection(...))
{
    SqlCommand cmd = new SqlCommand("sproc", conn);
    cmd.CommandType = CommandType.StoredProcedure;

    // add parameters

    conn.Open();

    // *** read output parameter here, how?
    conn.Close();
}
abatishchev
quelle

Antworten:

119

Die anderen Antwort zeigt dies, aber im Wesentlichen brauchen Sie nur zu erstellen SqlParameter, setzen Sie das Directionzu Output, und fügen Sie ihn in der SqlCommand‚s ParametersSammlung. Führen Sie dann die gespeicherte Prozedur aus und erhalten Sie den Wert des Parameters.

Verwenden Sie Ihr Codebeispiel:

// SqlConnection and SqlCommand are IDisposable, so stack a couple using()'s
using (SqlConnection conn = new SqlConnection(connectionString))
using (SqlCommand cmd = new SqlCommand("sproc", conn))
{
   // Create parameter with Direction as Output (and correct name and type)
   SqlParameter outputIdParam = new SqlParameter("@ID", SqlDbType.Int)
   { 
      Direction = ParameterDirection.Output 
   };

   cmd.CommandType = CommandType.StoredProcedure;
   cmd.Parameters.Add(outputIdParam);

   conn.Open();
   cmd.ExecuteNonQuery();

   // Some various ways to grab the output depending on how you would like to
   // handle a null value returned from the query (shown in comment for each).

   // Note: You can use either the SqlParameter variable declared
   // above or access it through the Parameters collection by name:
   //   outputIdParam.Value == cmd.Parameters["@ID"].Value

   // Throws FormatException
   int idFromString = int.Parse(outputIdParam.Value.ToString());

   // Throws InvalidCastException
   int idFromCast = (int)outputIdParam.Value; 

   // idAsNullableInt remains null
   int? idAsNullableInt = outputIdParam.Value as int?; 

   // idOrDefaultValue is 0 (or any other value specified to the ?? operator)
   int idOrDefaultValue = outputIdParam.Value as int? ?? default(int); 

   conn.Close();
}

Seien Sie vorsichtig, wenn Sie das bekommen Parameters[].Value, da der Typ von dem gegossen werden muss, als objectwas Sie ihn deklarieren. Und die SqlDbTypebeim Erstellen verwendeten SqlParameterAnforderungen müssen dem Typ in der Datenbank entsprechen. Wenn Sie es nur an die Konsole ausgeben Parameters["@Param"].Value.ToString()möchten , verwenden Sie es möglicherweise nur (entweder explizit oder implizit über einen Console.Write()oder einen String.Format()Aufruf).

EDIT: Über 3,5 Jahre und fast 20.000 Aufrufe und niemand hatte sich die Mühe gemacht zu erwähnen, dass es nicht einmal aus dem Grund kompiliert wurde, der in meinem "Vorsicht" -Kommentar im ursprünglichen Beitrag angegeben ist. Nett. Es wurde behoben, basierend auf guten Kommentaren von @Walter Stabosz und @Stephen Kennedy und passend zum Update-Code in der Frage von @abatishchev.

BQ.
quelle
8
Sie brauchen nicht, conn.Close()wie es in einem usingBlock ist
Marcus
1
Ich denke, Ihre Verwendung von int.MaxValue als Size-Eigenschaft ist falsch. int.MaxValue ist eine Konstante mit dem Wert 2.147.483.647. msdn.microsoft.com/en-us/library/… . Der Fehler ist in diesem Beispiel harmlos, da der Datentyp Int und "Bei Datentypen mit fester Länge wird der Wert von Size ignoriert." Ist, aber eine Null hätte ausgereicht.
Walter Stabosz
Der Wert ist vom Typ Objekt, daher funktioniert es nicht, ihn direkt einem Int ohne Casting zuzuweisen.
Stephen Kennedy
1
Wenn Sie einen DataReader verwenden, müssen Sie ihn schließen oder bis zum Ende der Daten lesen, bevor Sie die Ausgabeparameter anzeigen können.
Garry English
56

Wenn Sie mit der gespeicherten Prozedur etwas Ähnliches mit einem Reader tun möchten, beachten Sie, dass der Reader geschlossen sein muss, um den Ausgabewert abzurufen.

using (SqlConnection conn = new SqlConnection())
{
    SqlCommand cmd = new SqlCommand("sproc", conn);
    cmd.CommandType = CommandType.StoredProcedure;

    // add parameters
    SqlParameter outputParam = cmd.Parameters.Add("@ID", SqlDbType.Int);
    outputParam.Direction = ParameterDirection.Output;

    conn.Open();

    using(IDataReader reader = cmd.ExecuteReader())
    {
        while(reader.Read())
        {
            //read in data
        }
    }
    // reader is closed/disposed after exiting the using statement
    int id = outputParam.Value;
}
Nate Kindrew
quelle
4
Ich habe die Tatsache übersehen, dass der Reader geschlossen sein muss, bevor der Ausgabeparameter gelesen wird. Vielen Dank für den Hinweis!
Nicklas Møller Jepsen
28

Nicht mein Code, aber ein gutes Beispiel, denke ich

Quelle: http://www.eggheadcafe.com/PrintSearchContent.asp?LINKID=624

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


class OutputParams 
{ 
    [STAThread] 
    static void Main(string[] args) 
    { 

    using( SqlConnection cn = new SqlConnection("server=(local);Database=Northwind;user id=sa;password=;")) 
    { 
        SqlCommand cmd = new SqlCommand("CustOrderOne", cn); 
        cmd.CommandType=CommandType.StoredProcedure ; 

        SqlParameter parm= new SqlParameter("@CustomerID",SqlDbType.NChar) ; 
        parm.Value="ALFKI"; 
        parm.Direction =ParameterDirection.Input ; 
        cmd.Parameters.Add(parm); 

        SqlParameter parm2= new SqlParameter("@ProductName",SqlDbType.VarChar); 
        parm2.Size=50; 
        parm2.Direction=ParameterDirection.Output; 
        cmd.Parameters.Add(parm2); 

        SqlParameter parm3=new SqlParameter("@Quantity",SqlDbType.Int); 
        parm3.Direction=ParameterDirection.Output; 
        cmd.Parameters.Add(parm3);

        cn.Open(); 
        cmd.ExecuteNonQuery(); 
        cn.Close(); 

        Console.WriteLine(cmd.Parameters["@ProductName"].Value); 
        Console.WriteLine(cmd.Parameters["@Quantity"].Value.ToString());
        Console.ReadLine(); 
    } 
} 
WACM161
quelle
2
Ja, das ist richtig. Legen Sie einfach die ParameterDirection-Eigenschaft des Parameters fest. Sie brauchen die Zeile cn.Close () nicht - der using {} -Block kümmert sich darum.
MusiGenesis
6
string ConnectionString = ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString;
using (SqlConnection con = new SqlConnection(ConnectionString))
{
//Create the SqlCommand object
SqlCommand cmd = new SqlCommand(“spAddEmployee”, con);

//Specify that the SqlCommand is a stored procedure
cmd.CommandType = System.Data.CommandType.StoredProcedure;

//Add the input parameters to the command object
cmd.Parameters.AddWithValue(“@Name”, txtEmployeeName.Text);
cmd.Parameters.AddWithValue(“@Gender”, ddlGender.SelectedValue);
cmd.Parameters.AddWithValue(“@Salary”, txtSalary.Text);

//Add the output parameter to the command object
SqlParameter outPutParameter = new SqlParameter();
outPutParameter.ParameterName = @EmployeeId”;
outPutParameter.SqlDbType = System.Data.SqlDbType.Int;
outPutParameter.Direction = System.Data.ParameterDirection.Output;
cmd.Parameters.Add(outPutParameter);

//Open the connection and execute the query
con.Open();
cmd.ExecuteNonQuery();

//Retrieve the value of the output parameter
string EmployeeId = outPutParameter.Value.ToString();
}

Schriftart http://www.codeproject.com/Articles/748619/ADO-NET-How-to-call-a-stored-procedure-with-output

Vinícius Todesco
quelle
6
public static class SqlParameterExtensions
{
    public static T GetValueOrDefault<T>(this SqlParameter sqlParameter)
    {
        if (sqlParameter.Value == DBNull.Value 
            || sqlParameter.Value == null)
        {
            if (typeof(T).IsValueType)
                return (T)Activator.CreateInstance(typeof(T));

            return (default(T));
        }

        return (T)sqlParameter.Value;
    }
}


// Usage
using (SqlConnection conn = new SqlConnection(connectionString))
using (SqlCommand cmd = new SqlCommand("storedProcedure", conn))
{
   SqlParameter outputIdParam = new SqlParameter("@ID", SqlDbType.Int)
   { 
      Direction = ParameterDirection.Output 
   };

   cmd.CommandType = CommandType.StoredProcedure;
   cmd.Parameters.Add(outputIdParam);

   conn.Open();
   cmd.ExecuteNonQuery();

   int result = outputIdParam.GetValueOrDefault<int>();
}
Greg R Taylor
quelle
3

Sie können Ihr Ergebnis mit dem folgenden Code erhalten:

using (SqlConnection conn = new SqlConnection(...))
{
    SqlCommand cmd = new SqlCommand("sproc", conn);
    cmd.CommandType = CommandType.StoredProcedure;

    // add other parameters parameters

    //Add the output parameter to the command object
    SqlParameter outPutParameter = new SqlParameter();
    outPutParameter.ParameterName = "@Id";
    outPutParameter.SqlDbType = System.Data.SqlDbType.Int;
    outPutParameter.Direction = System.Data.ParameterDirection.Output;
    cmd.Parameters.Add(outPutParameter);

    conn.Open();
    cmd.ExecuteNonQuery();

    //Retrieve the value of the output parameter
    string Id = outPutParameter.Value.ToString();

    // *** read output parameter here, how?
    conn.Close();
}

quelle
2

Erstellen Sie das SqlParamObject, mit dem Sie den Zugriff auf Methoden für die Parameter steuern können

::

SqlParameter param = new SqlParameter ();

Stellen Sie den Namen für Ihren Parameter ein (er sollte so sein, als hätten Sie eine Variable deklariert, die den Wert in Ihrer Datenbank enthält).

:: param.ParameterName = "@yourParamterName";

Deaktivieren Sie den Wertehalter, um Ihre Ausgabedaten zu speichern

:: param.Value = 0;

Stellen Sie die Richtung Ihrer Wahl ein (in Ihrem Fall sollte es Ausgabe sein)

:: param.Direction = System.Data.ParameterDirection.Output;

Sandeep Pandey
quelle
1

Das sieht für mich expliziter aus:

int? id = outputIdParam.Value ist DbNull? Standard (int?): outputIdParam.Value;

Genn
quelle