2010-07-22 29 views
16

Tôi biết rằng có một câu hỏi khác có cùng tiêu đề, nhưng nó không trả lời câu hỏi của tôi. Tôi có một thủ tục được lưu trữ, trả về mã định danh duy nhất sau khi chèn (@@ identity). Tôi đã thử nó trong trình thám hiểm máy chủ và nó hoạt động như mong đợi (@RETURN_VALUE = [số nhận dạng]). Trong mã của tôi, tôi đã thêm một tham số được gọi là "@RETURN_VALUE", với hướng ReturnValue trước, hơn bất kỳ tham số nào khác, nhưng khi tôi chạy truy vấn của mình với ExecuteNonQuery(), tham số đó vẫn trống. Tôi không biết mình đã làm gì sai. SPROC của tôi:Nhận giá trị trả về từ thủ tục lưu sẵn trong ADO.NET

ALTER PROCEDURE dbo.SetAuction 
(
    @auctionID int, 
    @itemID int, 
    @auctionType tinyint, 
    @reservationPrice int, 
    @maxPrice int, 
    @auctionEnd datetime, 
    @auctionStart datetime, 
    @auctionTTL tinyint, 
    @itemName nchar(50), 
    @itemDescription nvarchar(MAX), 
    @categoryID tinyint, 
    @categoryName nchar(50) 
) AS 
IF @auctionID <> 0 
    BEGIN 
    BEGIN TRAN T1 

    UPDATE Auction 
    SET AuctionType = @auctionType, 
    ReservationPrice = @reservationPrice, 
    MaxPrice = @maxPrice, 
    AuctionEnd = @auctionEnd, 
    AuctionStart = @auctionStart, 
    AuctionTTL = @auctionTTL 
    WHERE AuctionID = @auctionID; 

    UPDATE Item 
    SET 
    ItemName = @itemName, 
    ItemDescription = @itemDescription 
    WHERE 
    ItemID = (SELECT ItemID FROM Auction WHERE AuctionID = @auctionID); 

    COMMIT TRAN T1 

    RETURN @auctionID 
    END 
ELSE 
    BEGIN 
    BEGIN TRAN T1 
    INSERT INTO Item(ItemName, ItemDescription, CategoryID) 
    VALUES(@itemName, @itemDescription, @categoryID); 

    INSERT INTO Auction(ItemID, AuctionType, ReservationPrice, MaxPrice, AuctionEnd, AuctionStart, AuctionTTL) 
    VALUES(@@IDENTITY,@auctionType,@reservationPrice,@maxPrice,@auctionEnd,@auctionStart,@auctionTTL); 
    COMMIT TRAN T1 
    RETURN @@IDENTITY 
    END 

Và mã của tôi là:

   cmd.CommandText = cmdText; 
       SqlParameter retval = new SqlParameter("@RETURN_VALUE", System.Data.SqlDbType.Int); 
       retval.Direction = System.Data.ParameterDirection.ReturnValue; 
       cmd.Parameters.Add(retval); 
       cmd.Parameters.AddRange(parameters); 
       cmd.Connection = connection; 

       connection.Open(); 
       cmd.ExecuteNonQuery(); 

       return (int)cmd.Parameters["@RETURN_VALUE"].Value; 
+0

Khi bạn nói 'trống' - bạn đang nhận được một ngoại lệ nói rằng 'Giá trị' là null? (Các diễn viên sẽ thất bại nếu nó là null). Hay là 0? –

+0

Giá trị là 0. – WebMonster

+4

BTW, '@@ IDENTITY' rất nguy hiểm; bạn nên sử dụng 'SCOPE_IDENTITY()' để thay thế. –

Trả lời

22

Chỉ cần cố gắng trên hộp của tôi và các công trình này cho tôi:

Trong SQL Server:

DROP PROCEDURE TestProc; 
GO 
CREATE PROCEDURE TestProc 
AS 
    RETURN 123; 
GO 

Trong C#

 string cnStr = "Server=.;Database=Sandbox;Integrated Security=sspi;"; 
     using (SqlConnection cn = new SqlConnection(cnStr)) { 
      cn.Open(); 
      using (SqlCommand cmd = new SqlCommand("TestProc", cn)) { 
       cmd.CommandType = CommandType.StoredProcedure; 
       SqlParameter returnValue = new SqlParameter(); 
       returnValue.Direction = ParameterDirection.ReturnValue; 
       cmd.Parameters.Add(returnValue); 

       cmd.ExecuteNonQuery(); 
       Assert.AreEqual(123, (int)returnValue.Value); 
      } 
     } 
+0

id get's value 0. – WebMonster

+0

Tôi đã mở rộng ví dụ. Có lẽ bạn sẽ thử điều này. –

3

Bạn có nhận được giá trị của bạn EXEC trong TSQL? Tôi tự hỏi nếu sắp xếp các TSQL sẽ giúp (và sử dụng SCOPE_IDENTITY():

nên thay đổi:

COMMIT TRAN T1 
RETURN @@IDENTITY 

tới:

SET @auctionID = SCOPE_IDENTITY() 
COMMIT TRAN T1 
RETURN @auctionID 

(Tôi cũng sẽ thay đổi khác @@IDENTITY để SCOPE_IDENTITY())


Là một tối ưu hóa nhỏ, bạn cũng có thể sử dụng:

return (int)retval.Value; 

nhưng bên này của điều nên đã làm việc "như là" từ những gì tôi có thể nhìn thấy (vì thế tại sao tôi đang tập trung vào các TSQL).

+0

Thay đổi những gì bạn đã đề xuất, nhưng không có hiệu lực. Tôi sử dụng "EXEC SetAuction @auctionID, ..." làm CommandText. Tôi nhận được giá trị trả lại nếu tôi chạy nó từ máy chủ thám hiểm (Visual Studio). – WebMonster

4

tôi giải quyết vấn đề: bạn phải thiết lập SqlCommand.CommandType đến CommandType.StoredProcedure để nhận giá trị trả về và/hoặc tham số đầu ra. Tôi đã không tìm thấy bất kỳ tài liệu nào về điều đó, nhưng bây giờ mọi thứ hoạt động.

1

Một số người ta cũng có thể sử dụng phương pháp đơn giản và ngắn này để tính toán giá trị trả về từ SP

Trong SQL:

Create Table TestTable 
(
Int Id 
) 

CREATE PROCEDURE Proc_TestProc 
@Id 
AS 
    Begin 
    Set NOCOUNT ON //Use this line if you don't want to return any message from SQL 

    Delete from TestTable where Id = @Id 
    return 1 

    Set NOCOUNT OFF //NOCOUNT OFF is Optional for NOCOUNT ON property 
    End 

Sql Server luôn trả về giá trị kiểu Int chỉ.

và trong C#

using (SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["TestConnectionString"].ToString())) 
using (SqlCommand cmd = new SqlCommand("Proc_TestProc", conn)) 
{ 
cmd.CommandType = CommandType.StoredProcedure; 

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

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

Bạn cũng có thể kiểm tra giá trị trả về của bạn trong SQL bằng cách sử dụng lệnh này:

DECLARE @return_status int; 
EXEC @return_status = dbo.[Proc_TestProc] 1; 
SELECT 'Return Status' = @return_status; 
print 'Returned value from Procedure: ' + Convert(varchar, @return_status); // Either previous or this line both will show you the value of returned value 
0

bạn có thể sử dụng cách standart mà bạn sử dụng trước trong các truy vấn bình thường nhưng trong lệnh Sql, bạn phải viết EXEC trước tên thủ tục lưu trữ của bạn và không sử dụng commandtype như sau:

SqlConnection con = new SqlConnection(["ConnectionString"]) 
    SqlCommand com = new SqlCommand("EXEC _Proc @id",con); 
    com.Parameters.AddWithValue("@id",["IDVALUE"]); 
    con.Open(); 
    SqlDataReader rdr = com.ExecuteReader(); 
    ArrayList liste = new ArrayList(); 
    While(rdr.Read()) 
    { 
    liste.Add(rdr[0]); //if it returns multiple you can add them another arrays=> liste1.Add(rdr[1]) .. 
    } 
    con.Close(); 
Các vấn đề liên quan