简体   繁体   English

如何从C#函数的存储过程中返回多个输出参数

[英]How to return multiple output parameters from stored procedure for C# function

I'm using output parameters to get values from my database. 我正在使用输出参数从数据库中获取值。

This is my stored procedure: 这是我的存储过程:

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

I'm not sure about the returns at the end: 我不确定最后的回报:

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

On the other side, here is the c# 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;
              }
          }
      }
}

When I run this code, I get error: 运行此代码时,出现错误:

System.InvalidOperationException: String[1]: the Size property has an invalid size of 0. System.InvalidOperationException:字符串[1]:Size属性的大小无效为0。
at System.Data.SqlClient.SqlParameter.Validate(Int32 index, Boolean isCommandProc) 在System.Data.SqlClient.SqlParameter.Validate(Int32索引,布尔isCommandProc)
at System.Data.SqlClient.SqlCommand.SetUpRPCParameters(_SqlRPC rpc, Int32 startCount, Boolean inSchema, SqlParameterCollection parameters) 在System.Data.SqlClient.SqlCommand.SetUpRPCParameters(_SqlRPC rpc,Int32 startCount,布尔inSchema,SqlParameterCollection参数)
at System.Data.SqlClient.SqlCommand.BuildRPC(Boolean inSchema, SqlParameterCollection parameters, _SqlRPC& rpc) 在System.Data.SqlClient.SqlCommand.BuildRPC(Boolean inSchema,SqlParameterCollection参数,_SqlRPC和rpc)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) 在System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior,RunBehavior runBehavior,布尔returnStream,布尔异步)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) 在System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior,RunBehavior runBehavior,布尔值returnStream,String方法,DbAsyncResult结果)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe) 在System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult结果,字符串methodName,布尔sendToPipe)
at System.Data.SqlClient.SqlCommand.ExecuteNonQuery() 在System.Data.SqlClient.SqlCommand.ExecuteNonQuery()

I don't know what is the correct way to send many output parameters from stored procedure, can someone help please? 我不知道从存储过程发送许多输出参数的正确方法是什么,有人可以帮忙吗?

You need to specify the maximum length for the nvarchar parameters: 您需要为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);

Remove the return statements from the stored procedure. 从存储过程中删除return语句。 You don't need to do anything for the output parameters to be returned. 您无需执行任何操作即可返回输出参数。 (Also, you can only use one return statement, and you can only return integer values. You would use a parameter with the direction ReturnValue to get that returned value.) (此外,您只能使用一个return语句,并且只能返回整数值。您将使用方向为ReturnValue的参数来获取该返回值。)

Procedure execution ends after your first RETURN which "Exits unconditionally from a query or procedure." 在您的第一个RETURN(“从查询或过程无条件退出”)之后,过程执行结束。

Consider returning both values as one recordset with 考虑将两个值作为一个记录集返回

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

at the end of the procedure. 在过程结束时。

>Try this its working fine for the multiple output parameter: >尝试此方法对于多个输出参数可以正常工作:

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

Here is what I tried and it is working fine 这是我尝试过的并且运行正常

**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 userid=@userid and pswd=@password
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 userid=@userid
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();
               }

             }
         }

SqlParameter SubscriptionPIN = new SqlParameter("@TheCustomerID", SqlDbType.NVarChar, 100) { Direction = ParameterDirection.Output }; SqlParameter SubscriptionPIN =新的SqlParameter(“ @ TheCustomerID”,SqlDbType.NVarChar,100){方向= ParameterDirection.Output}; cmd.Parameters.Add(SubscriptionPIN); cmd.Parameters.Add(SubscriptionPIN); SqlParameter SignupDate = new SqlParameter("@SignupDate", DbType.String, 100 ) { Direction = ParameterDirection.Output }; SqlParameter SignupDate =新的SqlParameter(“ @ SignupDate”, DbType.String,100 ){方向= ParameterDirection.Output}; cmd.Parameters.Add(SignupDate); cmd.Parameters.Add(SignupDate);

must give type and size 必须提供类型和大小

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM