ADO.NET에서 출력 매개 변수 값 가져 오기


96

내 저장 프로 시저에는 출력 매개 변수가 있습니다.

@ID INT OUT

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

답변:


119

다른 응답 프로그램이 있지만, 본질적으로 단지를 만들 필요가 SqlParameter의 설정 DirectionOutput, 그리고에 추가 SqlCommandParameters모음입니다. 그런 다음 저장 프로 시저를 실행하고 매개 변수 값을 가져옵니다.

코드 샘플 사용 :

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

를 가져올 때주의 Parameters[].Value해야합니다. 유형을 object선언 하는 형식으로 캐스팅해야하기 때문 입니다. 그리고 SqlDbType생성 할 때 사용되는 SqlParameter데이터베이스의 유형과 일치해야합니다. 콘솔에 출력하려는 ​​경우에는 Parameters["@Param"].Value.ToString()(명시 적으로 또는 묵시적으로 Console.Write()또는String.Format() 호출을 .

편집 : 3.5 년이 넘고 거의 20k의 조회수를 기록했으며 아무도 원래 게시물의 "주의"댓글에 지정된 이유로 컴파일하지 않았다고 언급하지 않았습니다. 좋은. @Walter Stabosz 및 @Stephen Kennedy의 좋은 의견을 기반으로 수정하고 @abatishchev의 질문에있는 업데이트 코드 편집과 일치하도록 수정했습니다.


8
블록 conn.Close()내부로 필요하지 않습니다using
Marcus

1
Size 속성으로 int.MaxValue를 사용하는 것이 잘못되었다고 생각합니다. int.MaxValue는 값이 2,147,483,647 인 상수입니다. msdn.microsoft.com/en-us/library/... . 이 예에서는 데이터 유형이 Int이고 "고정 길이 데이터 유형의 경우 Size 값이 무시됩니다."이므로 실수는 무해하지만 0이면 충분합니다.
Walter Stabosz

.Value는 객체 유형이므로 캐스팅하지 않고 int에 직접 할당하면 작동하지 않습니다.
Stephen Kennedy

1
DataReader를 사용하는 경우 출력 매개 변수를보기 전에 닫거나 데이터 끝까지 읽어야합니다.
Garry English

56

저장 프로 시저가있는 판독기를 사용하여 유사한 작업을 수행하려는 경우 출력 값을 검색하려면 판독기를 닫아야합니다.

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

4
출력 매개 변수를 읽기 전에 판독기를 닫아야한다는 사실을 놓쳤습니다. 지적 해 주셔서 감사합니다!
Nicklas Møller Jepsen

28

내 코드는 아니지만 좋은 예라고 생각합니다.

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

2
네, 맞습니다. 매개 변수의 ParameterDirection 속성을 설정하기 만하면됩니다. cn.Close () 줄은 필요하지 않습니다. using {} 블록이 처리합니다.
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();
}

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


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

3

아래 코드로 결과를 얻을 수 있습니다. :

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

2

매개 변수에 대한 액세스 메서드를 제어 할 수있는 SqlParamObject를 만듭니다.

:

SqlParameter param = 새로운 SqlParameter ();

매개 변수의 이름을 설정합니다 (데이터베이스에 값을 보유하기 위해 변수를 선언했을 때와 동일해야합니다).

: param.ParameterName = "@yourParamterName";

출력 데이터를 보유하려면 가치 보유자를 지우십시오.

: param.Value = 0;

선택한 방향 설정 (귀하의 경우 출력이어야 함)

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


1

저에게 더 분명해 보입니다.

int? id = outputIdParam.Value가 DbNull입니까? default (int?) : outputIdParam.Value;

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.