2012-10-14 35 views
5

Tôi đang sử dụng tham số đầu ra để lấy giá trị từ cơ sở dữ liệu của mình.Cách trả về nhiều tham số đầu ra từ thủ tục lưu sẵn cho hàm C#

Đây là thủ tục lưu trữ của tôi:

ALTER PROCEDURE [dbo].[sp_GetCustomerMainData] 
    -- Add the parameters for the stored procedure here 
     @Reference nvarchar(100), 
     @SubscriptionPIN nvarchar(100) OUTPUT, 
     @SignupDate nvarchar(100) OUTPUT, 
     @ProductCount int OUTPUT 
AS 
BEGIN 
    -- SET NOCOUNT ON added to prevent extra result sets from 
    -- interfering with SELECT statements. 
    SET NOCOUNT ON; 

    SET @SubscriptionPIN = 'N/A' 
    SET @SignupDate = 'N/A' 
    SET @ProductCount = 0 

    -- Insert statements for procedure here 
    IF EXISTS(SELECT [SubscriptionPIN] FROM [Norton].[dbo].[Customers] WHERE [Reference] = @Reference) 
    BEGIN 
     SELECT TOP 1 @SubscriptionPIN = [SubscriptionPIN], @SignupDate = SignUpDate FROM [Norton].[dbo].[ProductList] WHERE [Reference] = @Reference 
     SET @ProductCount = (SELECT COUNT(*) FROM [Norton].[dbo].[ProductList] WHERE [Reference] = @Reference) 
    END 

    RETURN (@SubscriptionPIN) 
    RETURN (@SignupDate) 
    RETURN (@ProductCount) 
END 

Tôi không chắc chắn về lợi nhuận ở cuối:

RETURN (@SubscriptionPIN) 
RETURN (@SignupDate) 
RETURN (@ProductCount) 

Ở phía bên kia, đây là đoạn code C#:

using (SqlConnection con = new SqlConnection(connectionInfo)) 
{ 
    using (SqlCommand cmd = new SqlCommand("sp_GetCustomerMainData", con) { CommandType = CommandType.StoredProcedure }) 
    { 
     cmd.Parameters.Add("@Reference", SqlDbType.NVarChar).Value = CustomerReferenceID; 

     SqlParameter SubscriptionPIN = new SqlParameter("@TheCustomerID", SqlDbType.NVarChar) { Direction = ParameterDirection.Output }; 
     cmd.Parameters.Add(SubscriptionPIN); 

     SqlParameter SignupDate = new SqlParameter("@SignupDate", SqlDbType.NVarChar) { Direction = ParameterDirection.Output }; 
     cmd.Parameters.Add(SignupDate); 

     SqlParameter ProductCount = new SqlParameter("@ProductCount", SqlDbType.Int) { Direction = ParameterDirection.Output }; 
     cmd.Parameters.Add(ProductCount); 

     con.Open(); 

     try 
     { 
      cmd.ExecuteNonQuery(); 

      if (cmd.Parameters["@TheCustomerID"].Value.ToString() != "N/A") 
      { 
       aStatus.SubscriptionPIN = cmd.Parameters["@TheCustomerID"].Value.ToString(); 
       aStatus.SignupDate = cmd.Parameters["@SignupDate"].Value.ToString(); 
       aStatus.ProductCount = int.Parse(cmd.Parameters["@ProductCount"].Value.ToString()); 
       aStatus.Result = "0: Reference ID Found"; 
      } 
      else 
      { 
       aStatus.Result = "1: Reference ID does not exists"; 
       return aStatus; 
      } 
      } 
      catch (SqlException sqlExc) 
      { 
       foreach (SqlError error in sqlExc.Errors) 
       { 
        aStatus.Result = string.Format("{0}: {1}", error.Number, error.Message); 
        return aStatus; 
       } 
      } 
     } 
} 

Khi tôi chạy mã này, tôi gặp lỗi:

System.InvalidOperationException: String[1]: the Size property has an invalid size of 0.
at System.Data.SqlClient.SqlParameter.Validate(Int32 index, Boolean isCommandProc)
at System.Data.SqlClient.SqlCommand.SetUpRPCParameters(_SqlRPC rpc, Int32 startCount, Boolean inSchema, SqlParameterCollection parameters)
at System.Data.SqlClient.SqlCommand.BuildRPC(Boolean inSchema, SqlParameterCollection parameters, _SqlRPC& rpc)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe)
at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()

Tôi không biết cách chính xác để gửi nhiều tham số đầu ra từ thủ tục được lưu trữ là gì, ai đó có thể giúp bạn không?

+1

bạn không sử dụng 'RETURN' cho các thông số đầu ra bạn chỉ cần gán một giá trị cho họ bên trong thủ tục. Nếu có nhiều hàng phù hợp trong 'ProductList WHERE Reference = @ Reference' (nghĩa là' @ ProductCount' là '> 1') thì không xác định được hàng nào sẽ được sử dụng khi gán cho' @SubscriptionPIN, @ SignupDate'. Cũng từ thông báo lỗi bạn đang nhận được trông giống như bạn cần sử dụng ['SqlParameter (String, SqlDbType, Int32)'] (http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlparameter .aspx) –

+0

Cảm ơn Martin, đã không nhận thấy câu trả lời của bạn ngay từ đầu, nhưng nó rất hữu ích. – Yasser

Trả lời

1

Bạn cần phải xác định độ dài tối đa cho các thông số nvarchar:

SqlParameter SubscriptionPIN = new SqlParameter("@TheCustomerID", SqlDbType.NVarChar, 100) { Direction = ParameterDirection.Output }; 
cmd.Parameters.Add(SubscriptionPIN); 
SqlParameter SignupDate = new SqlParameter("@SignupDate", SqlDbType.NVarChar, 100) { Direction = ParameterDirection.Output }; 
cmd.Parameters.Add(SignupDate); 

Tháo return báo cáo từ các thủ tục lưu trữ. Bạn không cần phải làm bất cứ điều gì cho các tham số đầu ra được trả về. (Ngoài ra, bạn chỉ có thể sử dụng một tuyên bố return và bạn chỉ có thể trả lại giá trị số nguyên. Bạn sẽ sử dụng thông số theo hướng ReturnValue để nhận giá trị trả lại đó.)

+0

Cảm ơn đã giải quyết được vấn đề của tôi, – Yasser

2

Thực hiện thủ tục kết thúc sau lần RETURN đầu tiên của bạn "Thoát khỏi vô điều kiện từ truy vấn hoặc thủ tục".

xem xét trở về cả hai giá trị như một recordset với

SELECT @SubscriptionPIN AS SubsPIN , @SignupDate AS SignUpDate, @ProductCount AS ProdCount 

ở phần cuối của quá trình.

+0

Cảm ơn câu trả lời của bạn, tôi thay đổi nó nhưng tôi vẫn gặp lỗi khi thực hiện, có bất kỳ thay đổi nào trong mã C# cần được thực hiện không? – Yasser

0

Đây là những gì tôi đã thử và đang hoạt động tốt

**Stored Procedures** 

STORED PROCEDURE 1 

create procedure spLoginCount 
@userid nvarchar(50), 
@password nvarchar(50), 
@count int out 
as 
Begin 
    select @count=count(userid) from users where [email protected] and [email protected] 
End 



**STORED PROCEDURE 2** 

create procedure spLoginData 
@userid nvarchar(50), 
@usertype nvarchar(20) out, 
@lastlogin nvarchar(100) out 
as 
Begin 
    select @usertype=usertype,@lastlogin=lastlogin from users where [email protected] 
End 


**ASP.NET code which will get values of two output Parameters**.... 



protected void btnLogin_Click(object sender, EventArgs e) 
    { 
     string uid="", psw=""; 
     uid = txtUserName.Text; 
     psw = txtPassword.Text; 

     string cs = ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString; 
     using (SqlConnection scon = new SqlConnection(cs)) 
     { 
      SqlCommand scmd = new SqlCommand("spLoginCount", scon); 
      scmd.CommandType = System.Data.CommandType.StoredProcedure; 
      scmd.Parameters.AddWithValue("@userid",uid); 
      scmd.Parameters.AddWithValue("@password", psw); 

      SqlParameter outparameter = new SqlParameter(); 
      outparameter.ParameterName = "@count"; 
      outparameter.SqlDbType = System.Data.SqlDbType.Int; 
      outparameter.Direction = System.Data.ParameterDirection.Output; 
      scmd.Parameters.Add(outparameter); 

      scon.Open(); 
      scmd.ExecuteScalar(); 

      string count = outparameter.Value.ToString(); 
      if (count == "1") 
      { 
       SqlCommand scmd1= new SqlCommand("spLoginData", scon); 
       scmd1.CommandType = System.Data.CommandType.StoredProcedure; 
       scmd1.Parameters.AddWithValue("@userid", uid); 

       /*SqlParameter outUserType = new SqlParameter(); 
       outUserType.ParameterName = "@usertype"; 
       outUserType.SqlDbType = System.Data.SqlDbType.NText; 
       outUserType.Direction = System.Data.ParameterDirection.Output; 
       scmd1.Parameters.Add(outUserType); 
       */ 
       SqlParameter outUserType = new SqlParameter("@usertype", SqlDbType.NVarChar, 100) { Direction = ParameterDirection.Output }; 
       scmd1.Parameters.Add(outUserType); 

       SqlParameter outLastLogin = new SqlParameter("@lastlogin", SqlDbType.NVarChar, 100) { Direction = ParameterDirection.Output }; 
       scmd1.Parameters.Add(outLastLogin); 

       scmd1.ExecuteNonQuery(); 
       scon.Close(); 

       string usertype,lastlogin; 
       usertype = outUserType.Value.ToString(); 
       lastlogin = outLastLogin.Value.ToString(); 
       } 

      } 
     } 
+1

Bạn có thể thử định dạng lại câu trả lời của mình để nó không hiển thị dưới dạng mã không? Cảm ơn. – A5C1D2H2I1M1N2O1R2T1

1

> Hãy thử điều này làm việc tốt cho các tham số đầu ra nhiều của nó:

using (SqlConnection sqlConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["conStringEndicia"].ConnectionString)){ 

       using (var sqlCmd = new SqlCommand("endicia.credentialLookup", sqlConnection)) 
       { 

        sqlCmd.CommandType = System.Data.CommandType.StoredProcedure; 
        sqlCmd.Parameters.AddWithValue("@accountNumber", accountNumber); 
        SqlParameter outLogin = new SqlParameter("@login", SqlDbType.NVarChar, 100) { Direction = ParameterDirection.Output }; 
        sqlCmd.Parameters.Add(outLogin); 
        SqlParameter outPassword = new SqlParameter("@password", SqlDbType.NVarChar, 100) { Direction = ParameterDirection.Output }; 
        sqlCmd.Parameters.Add(outPassword); 
        sqlConnection.Open(); 
        sqlCmd.ExecuteNonQuery(); 
        string login, password; 
        login = outLogin.Value.ToString(); 
        password = outPassword.Value.ToString();       
       } 
      } 
Các vấn đề liên quan