Dapatkan nilai parameter keluaran di ADO.NET

96

Prosedur tersimpan saya memiliki parameter keluaran:

@ID INT OUT

Bagaimana saya bisa mendapatkannya kembali menggunakan ado.net?

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
sumber

Jawaban:

119

Menunjukkan respon lainnya ini, tapi pada dasarnya Anda hanya perlu membuat SqlParameter, mengatur Directionuntuk Output, dan menambahkannya ke SqlCommand's Parameterskoleksi. Kemudian jalankan prosedur tersimpan dan dapatkan nilai parameternya.

Menggunakan contoh kode Anda:

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

Berhati-hatilah saat mendapatkan Parameters[].Value, karena jenisnya perlu diubah dari objectapa yang Anda nyatakan. Dan SqlDbTypedigunakan saat Anda membuat SqlParameterkebutuhan untuk mencocokkan tipe dalam database. Jika Anda hanya akan mengeluarkannya ke konsol, Anda mungkin hanya menggunakan Parameters["@Param"].Value.ToString()(baik secara eksplisit maupun implisit melalui fileConsole.Write()String.Format() panggilan atau ).

EDIT: Lebih dari 3,5 tahun dan hampir 20k tampilan dan tidak ada yang peduli untuk menyebutkan bahwa itu bahkan tidak dikompilasi untuk alasan yang ditentukan dalam komentar "hati-hati" saya di posting asli. Bagus. Diperbaiki berdasarkan komentar bagus dari @Walter Stabosz dan @Stephen Kennedy dan untuk mencocokkan kode pembaruan, edit dalam pertanyaan dari @abatishchev.

BQ.
sumber
8
Anda tidak perlu conn.Close()karena di dalam usingblok
Marcus
1
Saya pikir penggunaan int.MaxValue sebagai properti Size tidak benar. int.MaxValue adalah konstanta dengan nilai 2,147,483,647. msdn.microsoft.com/en-us/library/… . Kesalahan tidak berbahaya dalam contoh ini karena tipe data adalah Int dan "Untuk tipe data dengan panjang tetap, nilai Ukuran diabaikan.", Tetapi nol sudah cukup.
Walter Stabosz
.Nilai adalah tipe objek, jadi menugaskannya langsung ke int tanpa casting tidak akan berhasil.
Stephen Kennedy
1
Bagi mereka yang menggunakan DataReader, Anda harus menutupnya atau membaca sampai akhir data sebelum Anda dapat melihat parameter output.
Garry English
56

Untuk siapa pun yang ingin melakukan sesuatu yang serupa menggunakan reader dengan prosedur tersimpan, perhatikan bahwa reader harus ditutup untuk mengambil nilai output.

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
sumber
4
Saya melewatkan fakta bahwa pembaca harus ditutup sebelum membaca parameter keluaran. Terima kasih telah menunjukkannya!
Nicklas Møller Jepsen
28

Bukan kode saya, tapi saya pikir contoh yang bagus

sumber: 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
sumber
2
Ya, ini benar. Cukup setel properti ParameterDirection dari parameter. Anda tidak membutuhkan baris cn.Close () - blok using {} akan mengurusnya.
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();
}

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

Vinícius Todesco
sumber
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
sumber
3

Anda bisa mendapatkan hasil Anda dengan kode di bawah ini:

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

sumber
2

Buat SqlParamObject yang akan memberi Anda kontrol untuk mengakses metode pada parameter

:

SqlParameter param = new SqlParameter ();

SET Nama untuk parameter Anda (itu harus b sama seperti Anda akan mendeklarasikan variabel untuk menyimpan nilai di DataBase Anda)

: param.ParameterName = "@yourParamterName";

Hapus pemegang nilai untuk menampung data keluaran Anda

: param.Value = 0;

Tetapkan Arah Pilihan Anda (Dalam kasus Anda itu harus Output)

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

Sandeep Pandey
sumber
1

Itu terlihat lebih eksplisit bagi saya:

int? id = outputIdParam.Value adalah DbNull? default (int?): outputIdParam.Value;

Genn
sumber