【问题标题】:Return value from stored procedure to c#从存储过程返回值到c#
【发布时间】:2012-09-12 10:30:21
【问题描述】:

我在另外一个存储过程中遇到了同样的问题。 我想向 SQL Server 2008 数据库添加请假请求。我可以成功运行存储过程,但是从页面中我无法返回操作是否完成或不完整的状态。

我正在通过 SP 发送数据,但无法通过程序获取状态。

我的存储过程是:

ALTER Procedure [dbo].[Check_LeaveDays](
@EmpCode int,
@LV_Type int,
@Leave_AppDt DateTime,
@Leave_ToDate Datetime ,
@LV_Days int
,@Status_Id int Output
)

as
Begin 

    Declare @Dt_join datetime ,@LastDate Datetime
    Declare @Count int 
    Declare @Leave_Status_Id int 
    Declare @Leave_period int 
    Declare @Rule_id int 
    Declare @Leave_AllocatedDays int
    Declare @Leave_MaxDays int 
    Declare @Days_diff int
--  Declare @Status_Id int
--  Set @Status_Id= 0
        Select @Dt_Join =Emp_DOJ from LTS_Employee_Master where Emp_ID =4

        Select @LastDate= DATEADD(year, DATEDIFF(year, -1, getdate()), -1)
        Select @Days_diff=0

        If(YEAR(@Dt_Join) =  YEAR(GETDATE()))
        Begin 
            Select @Days_diff = DATEDIFF(D, @Dt_Join,@LastDate) 
        End 


    --Select @Leave_AppDt = dateadd(M, -2, getdate())


            Select @Rule_id = Case when @LV_Type =1 then ISNULL(Emp_Casual_rule,0)
            when @LV_Type =2 then ISNULL(Emp_Medical_rule,0)  
            when @LV_Type =3 then ISNULL(Emp_PL_rule,0)  
                    else 0 End 
                from LTS_Employee_Master where Emp_ID =@Empcode 

    If @LV_Type =1
    Begin 
                Select @Leave_AllocatedDays = LPM_Allocated_Days ,@Leave_MaxDays =LPM_Max_Days ,@Leave_period =LPM_Count 
                from LTS_Leave_Policy_Master where LPM_Id =@Rule_Id 
    If   @Days_diff <> 0
    Begin 
            Select @Leave_AllocatedDays = 365/@Leave_AllocatedDays
            Select @Leave_AllocatedDays = @Days_diff / @Leave_AllocatedDays
    End
                Select  @Count =Sum(Leave_Days)  
                from LTS_Emp_Leave_Requests where Leave_Emp_ID =@empcode and Leave_type_Id=1 and Leave_Status_ID=1 and YEAR(@Leave_ToDate) =YEAR(leave_to_Date) 

                    Select  @Count = ISNULL(@Count,0) + ISNULL(Sum(Leave_Days),0)  
                    from LTS_Emp_Leave_Requests where Leave_Emp_ID =@empcode and Leave_type_Id=1 and Leave_Status_ID=3 and YEAR(@Leave_ToDate) =YEAR(leave_to_Date) 
                    and Req_id not in(Select Req_id   from LTS_Emp_Leave_Requests where Leave_Emp_ID =@empcode and Leave_type_Id=1 and Leave_Status_ID=3 and YEAR(@Leave_ToDate) =YEAR(leave_to_Date)) 

                Select  @Count = ISNULL(@Count,0) + ISNULL(Sum(Leave_Days),0)  
                from LTS_Emp_Leave_Requests where Leave_Emp_ID =@empcode and Leave_type_Id=1 and Leave_Status_ID=3 and YEAR(@Leave_ToDate) =YEAR(leave_to_Date) 
                and Req_id not in(Select Req_id   from LTS_Emp_Leave_Requests where Leave_Emp_ID =@empcode and Leave_type_Id=1 and Leave_Status_ID=3 and YEAR(@Leave_ToDate) =YEAR(leave_to_Date)) 

                Select @count,@Leave_MaxDays 

    if(@LV_Days > @Leave_MaxDays)
    Begin  

                Set @Status_Id=1 -- Status appliation leave days is more than allowance max days at a time 

    End  


    If(@Count  > @Leave_AllocatedDays)
    Begin 
                Select @Status_Id =2 --Status 2 applies for numbers of maximum  days applied is more than actual allocated maximum number of days 

    End 

                Select  @Count =Sum(Leave_Days)  
                from
                (Select  top 1  *  from  LTS_Emp_Leave_Requests  order by Leave_ID desc) Temp
                where Leave_Emp_ID =@empcode and Leave_type_Id=1 and Leave_Status_ID =1   group by Leave_Emp_Id

                Declare @tbl table(Leave_Id int , Leave_Status_Id int , Leave_To_date datetime,leave_days int,
                Leave_Emp_Id int,Leave_off_Id int,Req_Id int,leave_LPM_ID int, leave_type_Id int)
                Insert into @tbl 
                Select top 1
                Leave_Id  , Leave_Status_Id , Leave_To_date ,
                Leave_days ,Leave_Emp_Id ,Leave_off_Id ,Req_Id ,leave_LPM_ID , Leave_type_Id 
                from LTS_Emp_Leave_Requests where Leave_Emp_ID =@empcode and Leave_Status_ID  in(1,3,5) order by Leave_ID desc

    Select @Leave_ToDate =Leave_To_date from @tbl 
    If( DATEDIFF(D,@Leave_ToDate, DATEADD(D,-1, @Leave_AppDt)) > @Leave_AllocatedDays)
    Begin
            Select @Status_Id =3
    End  
    End 
    Return @Status_Id

结束

我的存储过程调用函数:

public string SendRequestDataSql(int empid, int leavetype, DateTime fromdate, DateTime todate, int leavedays)
    {
        string retunvalue="0";
        DataTable dt = new DataTable();
        try
        {
            SqlConnection sqlConnection = new SqlConnection();
            string conString = Connection.GetConnection;

            using (SqlConnection con = new SqlConnection(conString))
            {
                //sqlConnection.Open();
                using (SqlCommand cmd = new SqlCommand("Check_LeaveDays", con))
                {      


                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.Add("@EmpCode", SqlDbType.VarChar, 10).Value = empid;
                    cmd.Parameters.Add("@LV_Type", SqlDbType.VarChar, 10).Value = leavetype;
                    cmd.Parameters.Add("@Leave_AppDt", SqlDbType.VarChar,15).Value = fromdate;
                    cmd.Parameters.Add("@Leave_ToDate", SqlDbType.VarChar,15).Value = todate;
                    cmd.Parameters.Add("@LV_Days", SqlDbType.VarChar,10).Value = leavedays;

                 SqlParameter returnParameter = cmd.Parameters.Add("RetVal", SqlDbType.Int); 
                    returnParameter.Direction = ParameterDirection.ReturnValue; 

                    con.Open();
                    int itrrr = Convert.ToInt32( cmd.ExecuteNonQuery());

                    int returnValue = (int)returnParameter.Value; 
                    //message = Convert.ToInt32(objparm.Value);

                    con.Close();




                    using (SqlDataAdapter da = new SqlDataAdapter(cmd))
                    {
                        DataSet ds = new DataSet();
                        da.Fill(ds);
                        dt = ds.Tables[0];
                    }
                }
            }
        }
        catch (SqlException ex)
        {

        }
        return retunvalue;
    }

【问题讨论】:

标签: c# asp.net sql-server sql-server-2008


【解决方案1】:

请将您的代码编辑为:

删除这一行:

 cmd.Parameters.Add("@Status", SqlDbType.Int).Value = status;

添加此代码:

 SqlParameter abc = cmd.Parameters.Add("@Status", SqlDbType.Int);
 abc.Direction = ParameterDirection.Output;

然后你可以得到你的状态结果在 abc。

希望这会对你有所帮助。

【讨论】:

  • 以上更改给了我这个错误:Procedure or function 'SP_Designation_Add' expects parameter '@Status', which was not supplied. >>如何解决这个问题?我已经尝试过这个解决方案
  • 能否用您当前的代码更新上述代码。
  • 代码在我当前的场景中更新,当我将它添加到 dbml 时,它表明我声明了许多匿名列。怎么处理?
  • 在您的程序中,您已声明 @Status_Id int 两次。请更正一次并让我们知道它是否有效。
  • -- Declare @Status_Id int -- Set @Status_Id= 0 在声明区被评论!
【解决方案2】:

在存储过程中

RETURN @status

在 C# 中

string retunvalue = (string)sqlcomm.Parameters["@status"].Value;

【讨论】:

  • 可以返回字符串吗?我的返回值只有 1 或 2 或 3。 No Database Connection的初始值设置为0
  • 那么public int? AddNewDesigDataSql(string desig_name, string Details, int AddedBy) 呢?这里int? 替换成string 可以吗?
【解决方案3】:
public int? AddNewDesigDataSql(string desig_name, string Details, int AddedBy)
    {
        int? status = 0;
        DataTable dt = new DataTable();
        try
        {
            SqlConnection sqlConnection = new SqlConnection();
            string conString = Connection.GetConnection;

            using (SqlConnection con = new SqlConnection(conString))
            {
                con.Open();

                using (SqlCommand cmd = new SqlCommand("SP_Dedignation_Add", con))
                {
                    cmd.CommandType = CommandType.StoredProcedure;

                    SqlParameter param1=cmd.Parameters.Add("@Desig_Name", SqlDbType.varchar,500).Value = desig_name;
 param1.Direction = ParameterDirection.Input;

                    SqlParameter param2=cmd.Parameters.Add("@Desig_Desc", SqlDbType.varchar,500).Value = Details;
param2.Direction = ParameterDirection.Input;

                    SqlParameter param3=cmd.Parameters.Add("@Desig_AddedBy", SqlDbType.int,8).Value = AddedBy;
param3.Direction = ParameterDirection.Input;

                    SqlParameter param4=cmd.Parameters.Add("@Status", SqlDbType.Int).Value = status;

param4.Direction = ParameterDirection.Output;


                    cmd.ExecuteNonQuery();
                    con.Close();

                    status = (int)param4.Value;

                    using (SqlDataAdapter da = new SqlDataAdapter(cmd))
                    {
                        DataSet ds = new DataSet();
                        da.Fill(ds);
                        dt = ds.Tables[0];
                    }
                }
            }
        }
        catch (SqlException ex)
        {

        }
        return status;
    }

【讨论】:

  • 这给出了如下错误:Error 53 Cannot implicitly convert type 'object' to 'System.Data.SqlClient.SqlParameter'. An explicit conversion exists (are you missing a cast?) D:\&lt;address&gt;DesignationDAL.cs 35 47 LTS_DAL
  • 代码在我当前的场景中更新,当我将它添加到 dbml 时,它表明我声明了许多匿名列。怎么处理?
  • 没有。它没有返回状态。它只给我的初始值0。如何获取返回值?在我的项目中,所有操作都是由 linqtosql 完成的,但我无法将此 SP 添加到 .dbml,因为它包含多个匿名列。如何重新配置​​查询或任何可用的解决方案?查询在后端工作正常。我不能把它配置到前端!
  • 无法提取存储过程“dbo.Check_LeaveDays”,因为其结果集包含多个匿名列。这是错误。我第一次遇到这个错误,不知道该怎么办!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-18
  • 2020-01-07
  • 1970-01-01
相关资源
最近更新 更多