Nhận giá trị tham số đầu ra trong ADO.NET


96

Thủ tục được lưu trữ của tôi có tham số đầu ra:

@ID INT OUT

Tôi làm cách nào để lấy thông tin này bằng cách sử dụng 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();
}

Câu trả lời:


119

Các chương trình phản ứng khác này, nhưng về cơ bản bạn chỉ cần tạo ra một SqlParameter, thiết lập Directionđể Output, và thêm nó vào SqlCommand's Parameterssưu tập. Sau đó thực hiện thủ tục đã lưu trữ và nhận giá trị của tham số.

Sử dụng mẫu mã của bạn:

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

Hãy cẩn thận khi lấy Parameters[].Value, vì kiểu cần được chuyển từ kiểu objectmà bạn đang khai báo. Và SqlDbTypeđược sử dụng khi bạn tạo SqlParameternhu cầu để phù hợp với loại trong cơ sở dữ liệu. Nếu bạn chỉ xuất nó ra bảng điều khiển, bạn có thể đang sử dụng Parameters["@Param"].Value.ToString()(rõ ràng hoặc ẩn ý thông qua một Console.Write()hoặc một String.Format()cuộc gọi).

CHỈNH SỬA: Hơn 3,5 năm và gần 20 nghìn lượt xem và không ai bận tâm đến việc nó thậm chí không được biên dịch vì lý do được chỉ định trong nhận xét "hãy cẩn thận" của tôi trong bài đăng gốc. Đẹp. Đã sửa lỗi dựa trên nhận xét tốt từ @Walter Stabosz và @Stephen Kennedy và để khớp với chỉnh sửa mã cập nhật trong câu hỏi từ @abatishchev.


8
Bạn không cần conn.Close()nó bên trong một usingkhối
Marcus

1
Tôi nghĩ rằng việc bạn sử dụng int.MaxValue làm thuộc tính Size là không chính xác. int.MaxValue là một hằng số có giá trị 2,147,483,647. msdn.microsoft.com/en-us/library/… . Sai lầm là vô hại trong ví dụ này vì kiểu dữ liệu là Int và "Đối với các kiểu dữ liệu có độ dài cố định, giá trị của Kích thước bị bỏ qua.", Nhưng số 0 là đủ.
Walter Stabosz

.Value là đối tượng kiểu, vì vậy việc gán trực tiếp nó cho một int mà không cần truyền sẽ không hoạt động.
Stephen Kennedy

1
Đối với những người đang sử dụng DataReader, bạn phải đóng nó hoặc đọc đến cuối dữ liệu trước khi bạn có thể xem các tham số đầu ra.
Garry English

56

Đối với bất kỳ ai muốn làm điều gì đó tương tự bằng cách sử dụng trình đọc với quy trình được lưu trữ, hãy lưu ý rằng trình đọc phải được đóng để truy xuất giá trị đầu ra.

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
Tôi đã bỏ lỡ thực tế là đầu đọc phải được đóng trước khi đọc tham số đầu ra. Cảm ơn vì đã chỉ ra điều đó!
Nicklas Møller Jepsen

28

Không phải mã của tôi, mà là một ví dụ điển hình mà tôi nghĩ

nguồn: 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
Đúng, điều này là chính xác. Chỉ cần đặt thuộc tính ParameterDirection của tham số. Bạn không cần dòng cn.Close () - khối using {} sẽ giải quyết việc đó.
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();
}

Phông chữ 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

Bạn có thể nhận được kết quả của mình bằng mã bên dưới ::

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

Tạo SqlParamObject sẽ cung cấp cho bạn quyền kiểm soát truy cập các phương thức trên các tham số

:

SqlParameter tham số = new SqlParameter ();

ĐẶT Tên cho tham số của bạn (nó phải giống như bạn đã khai báo một biến để giữ giá trị trong DataBase của bạn)

: param.ParameterName = "@yourParamterName";

Xóa giá trị để giữ cho bạn dữ liệu đầu ra

: param.Value = 0;

Đặt hướng lựa chọn của bạn (Trong trường hợp của bạn, nó phải là Đầu ra)

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


1

Điều đó có vẻ rõ ràng hơn đối với tôi:

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.