Gọi thủ tục được lưu trữ với giá trị trả về


82

Tôi đang cố gọi một thủ tục được lưu trữ từ ứng dụng C # windows của mình. Thủ tục được lưu trữ đang chạy trên phiên bản cục bộ của SQL Server 2008. Tôi có thể gọi thủ tục được lưu trữ nhưng tôi không thể lấy lại giá trị từ thủ tục được lưu trữ. Thủ tục được lưu trữ này được cho là trả về số tiếp theo trong chuỗi. Tôi đã thực hiện nghiên cứu trực tuyến và tất cả các trang web tôi đã xem đều chỉ ra giải pháp này hoạt động.

Mã thủ tục được lưu trữ:

ALTER procedure [dbo].[usp_GetNewSeqVal]
      @SeqName nvarchar(255)
as
begin
      declare @NewSeqVal int
      set NOCOUNT ON
      update AllSequences
      set @NewSeqVal = CurrVal = CurrVal+Incr
      where SeqName = @SeqName

      if @@rowcount = 0 begin
print 'Sequence does not exist'
            return
      end

      return @NewSeqVal
end

Mã gọi thủ tục được lưu trữ:

SqlConnection conn = new SqlConnection(getConnectionString());
conn.Open();

SqlCommand cmd = new SqlCommand(parameterStatement.getQuery(), conn);
cmd.CommandType = CommandType.StoredProcedure;

SqlParameter param = new SqlParameter();

param = cmd.Parameters.Add("@SeqName", SqlDbType.NVarChar);
param.Direction = ParameterDirection.Input;
param.Value = "SeqName";

SqlDataReader reader = cmd.ExecuteReader();

Tôi cũng đã thử sử dụng a DataSetđể truy xuất giá trị trả về với kết quả tương tự. Tôi còn thiếu gì để nhận giá trị trả về từ thủ tục đã lưu trữ của mình? Nếu cần thêm thông tin, xin vui lòng cho tôi biết.

Câu trả lời:


165

Bạn cần thêm tham số trả về vào lệnh:

using (SqlConnection conn = new SqlConnection(getConnectionString()))
using (SqlCommand cmd = conn.CreateCommand())
{
    cmd.CommandText = parameterStatement.getQuery();
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.Parameters.AddWithValue("SeqName", "SeqNameValue");

    var returnParameter = cmd.Parameters.Add("@ReturnVal", SqlDbType.Int);
    returnParameter.Direction = ParameterDirection.ReturnValue;

    conn.Open();
    cmd.ExecuteNonQuery();
    var result = returnParameter.Value;
}

3
Bạn có phải thêm @ReturnValvào Thủ tục lưu trữ không?
muttley91

4
Không, bạn không cần phải thêm vào các sp (các trigger lệnh return điền các thông số được đánh dấu bằng returnValue)
ufosnowcat

10
Không quan trọng bạn đặt tên cho tham số val trả về, btw.
Clay

cảm ơn rất nhiều, tôi đang tìm cách để nhận được giá trị trả lại đúng cách, điều này thực sự hiệu quả với tôi. tuyệt vời!
Oswaldo Zapata

4
Giá trị trả về của thủ tục được lưu trữ chỉ nên được sử dụng để biểu thị thành công (không) hoặc thất bại / cảnh báo (khác 0), không trả về dữ liệu. Sử dụng một OUTPUTtham số hoặc tập kết quả cho mục đích đó.
Dan Guzman

5

Tôi biết điều này đã cũ, nhưng tôi đã vấp phải nó với Google.

Nếu bạn có giá trị trả về trong thủ tục đã lưu trữ của mình, hãy nói "Trả về 1" - không sử dụng các tham số đầu ra.

Bạn có thể làm như sau - "@RETURN_VALUE" được thêm âm thầm vào mọi đối tượng lệnh. KHÔNG CẦN PHẢI THÊM

    cmd.ExecuteNonQuery();
    rtn = (int)cmd.Parameters["@RETURN_VALUE"].Value;

2
Chào Gary. Bạn có tình cờ có một trích dẫn?
Michael

5
Tôi không tin rằng phiên bản cmd sẽ có một tham số có tên trong RETURN_VALUE trong SqlParameterCollection trừ khi nó được thêm một cách rõ ràng. Do đó, nếu bạn đang cân nhắc thực hiện cách tiếp cận ở trên của Gary, thì hãy đảm bảo rằng bạn đã thêm cmd.Parameters.Add (new SqlParameter ("@ RETURN_VALUE", SqlDbType.Int)); cmd.Parameters ["@ RETURN_VALUE"]. Direction = ParameterDirection.ReturnValue; Tuy nhiên, tôi tin rằng bạn KHÔNG phải thêm @RETURN_VALUE vào định nghĩa thủ tục được lưu trữ. Có lẽ đó là ý của Gary.
jbooker

4

Phiên bản EnterpriseLibrary trên máy của tôi có các thông số khác. Điều này đã hoạt động:

        SqlParameter retval = new SqlParameter("@ReturnValue", System.Data.SqlDbType.Int);
        retval.Direction = System.Data.ParameterDirection.ReturnValue;
        cmd.Parameters.Add(retval);
        db.ExecuteNonQuery(cmd);
        object o = cmd.Parameters["@ReturnValue"].Value;

3

ExecuteScalar () sẽ hoạt động, nhưng một tham số đầu ra sẽ là một giải pháp tốt hơn.


6
ExecuteScalar () không hoạt động, trừ khi bạn "chọn" giá trị trả về.
Soori


2

Tôi đã gặp sự cố tương tự với cuộc gọi SP trả về lỗi không bao gồm tham số mong đợi. Mã của tôi như sau.
Thủ tục lưu trữ:

@Result int OUTPUT

Và C#:

            SqlParameter result = cmd.Parameters.Add(new SqlParameter("@Result", DbType.Int32));
            result.Direction = ParameterDirection.ReturnValue;

Khi khắc phục sự cố, tôi nhận ra rằng thủ tục được lưu trữ THỰC SỰ đang tìm kiếm hướng của "InputOutput" vì vậy thay đổi sau đã khắc phục sự cố.

            r

Result.Direction = ParameterDirection.InputOutput;


"Tham số đầu ra" không giống với giá trị trả về của Thủ tục lưu trữ, btw.
Đài

0

Hoặc nếu bạn đang sử dụng EnterpriseLibrary thay vì ADO.NET tiêu chuẩn ...

Database db = DatabaseFactory.CreateDatabase();
using (DbCommand cmd = db.GetStoredProcCommand("usp_GetNewSeqVal"))
{
    db.AddInParameter(cmd, "SeqName", DbType.String, "SeqNameValue");
    db.AddParameter(cmd, "RetVal", DbType.Int32, ParameterDirection.ReturnValue, null, DataRowVersion.Default, null);

    db.ExecuteNonQuery(cmd);

    var result = (int)cmd.Parameters["RetVal"].Value;
}

0

Đây là một mẫu rất ngắn để trả về một giá trị duy nhất từ ​​một thủ tục:

SQL:

CREATE PROCEDURE [dbo].[MakeDouble] @InpVal int AS BEGIN 
SELECT @InpVal * 2; RETURN 0; 
END

C # -code:

int inpVal = 11;
string retVal = "?";
using (var sqlCon = new SqlConnection(
    "Data Source = . ; Initial Catalog = SampleDb; Integrated Security = True;"))
{
    sqlCon.Open();
    retVal = new SqlCommand("Exec dbo.MakeDouble " + inpVal + ";", 
        sqlCon).ExecuteScalar().ToString();
    sqlCon.Close();
}
Debug.Print(inpVal + " * 2 = " + retVal); 
//> 11 * 2 = 22

-8

Tôi thấy cái kia đã đóng cửa. Vì vậy, về cơ bản đây là đoạn mã thô của tôi. Tôi nghĩ rằng bạn đang thiếu bình luận cmd chuỗi. Ví dụ: nếu thủ tục cửa hàng của tôi là gọi: DBO.Test. Tôi sẽ cần viết cmd = "DBO.test". Sau đó gõ lệnh bằng thủ tục lưu trữ và blah blah blah

Connection.open();
String cmd="DBO.test"; //the command
Sqlcommand mycommand;

câu trả lời tuyệt vời, vỗ tay vỗ tay
Janatbek Sharsheyev 27/02
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.