简体   繁体   中英

Sql error “Procedure or function expects parameter , which was not supplied” when calling a stored procedure from c# code

I have a stored procedure that takes three parameters:

  1. AccountId
  2. StartDate
  3. EndDate

When I execute it directly from SQL Server Management Studio, it does not show any error, but when I call it from my application I get this error

Procedure or function 'GetSubscribersForAccountID_With_Dates' expects parameter '@AccountId', which was not supplied.

Here is the stored procedure :

ALTER PROCEDURE [dbo].[GetSubscribersForAccountID_With_Dates]
    @AccountId  as Int ,
    @StartDate DATETIME = null,
    @EndDate DATETIME = null
AS
BEGIN
    SET NOCOUNT ON;

     --- BODY ---
    DECLARE @SQL AS NVARCHAR(MAX)

    SET @SQL =' SELECT   phone_num AS MSISDN1,'
        +' number AS MSISDNID,'
        + 'parentaccount AS PARENT_ACCOUNT,'
        + 'account_no AS AccountID,'
       + 'service_fname AS FirstName,'
       + 'service_lname AS LastName,'
      + ' service_active_dt AS startdate,'
       + 'service_inactive_dt AS enddate '
   + ' FROM     [myTable]'
   + ' WHERE    parent_account =  ' + CONVERT(VARCHAR, @AccountId)

      If (@StartDate is not null And @EndDate is not null)
      Begin
          SET @SQL += ' AND service_active_dt <= '''+ CONVERT(VARCHAR(20),   @EndDate,101)
          SET @SQL += ''' AND  (service_inactive_dt is null or service_inactive_dt >= ''' + CONVERT(varchar, @StartDate,101)+''')'
      End
      Else 
          SET @SQL += ' AND service_inactive_dt is  null ' 

      --Debug
      print(@SQL)

    EXEC SP_EXECUTESQL @SQL
END

The method that calls the stored procedure:

 public List<MSISDN> GetListOfSubscribersByAccountID_WithDates(int accountID, DateTime? from = null, DateTime? to = null) 
 {
        List<MSISDN> lstMsisdn = new List<MSISDN>();
        string spName = "GetSubscribersForAccountID_With_Dates";

        IDbCommand cmd = CreateCommand(spName);  

        //Adding parameters

        DbParameter param;
        param = new SqlParameter("@AccountId", accountID);
        param.DbType = DbType.Int32;
        param.Direction = ParameterDirection.Input;
        cmd.Parameters.Add(param);

        if (from != null)
        {
            param = new SqlParameter("@StartDate", from);
            param.DbType = DbType.DateTime;
            param.Direction = ParameterDirection.Input;
            cmd.Parameters.Add(param);
        }

        if (to != null)
        {
            param = new SqlParameter("@EndDate", to);
            param.DbType = DbType.DateTime;
            param.Direction = ParameterDirection.Input;
            cmd.Parameters.Add(param);
        }



        try
        {
            using (IDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleResult))
            {
                while (reader.Read())
                {
                    lstMsisdn.Add(GetSubscribersFromReader(reader));
                }
            }

            return lstMsisdn;

        }
        catch (Exception ex)
        {

            throw ex;
        }
        finally
        {
            if (this.Connection != null)
                this.Connection.Close();
        }
    }

You're just not telling ADO.NEt that you want to execute a stored procedure - add this:

IDbCommand cmd = CreateCommand(spName);  
// Add this to make clear that you want to call a stored procedure
cmd.CommandType = CommandType.StoredProcedure;

Your stored procedure is prone to sql-injection, use parameterisation as follows:

ALTER PROCEDURE [dbo].[GetSubscribersForAccountID_With_Dates]
@AccountId  as Int ,
@StartDate DATETIME = null,
@EndDate DATETIME = null
AS
BEGIN
SET NOCOUNT ON;

      --- BODY ---
DECLARE @SQL AS NVARCHAR(MAX)

SET @SQL =' SELECT   phone_num AS MSISDN1,
                    number AS MSISDNID,
                    parentaccount AS PARENT_ACCOUNT,
                    account_no AS AccountID,
                    service_fname AS FirstName,
                    service_lname AS LastName,
                    service_active_dt AS startdate,
                    service_inactive_dt AS enddate 
             FROM     [myTable]
             WHERE    parent_account =  @AccountId'
        + CASE WHEN @StartDate is not null And @EndDate is not null
          THEN 'AND service_active_dt <=  @EndDate
                AND  (service_inactive_dt is null 
                        or 
                       service_inactive_dt >=  @StartDate )' 
           ELSE 'AND service_inactive_dt is  null' END 

    EXEC SP_EXECUTESQL @SQL
                      ,N'@AccountId INT , @StartDate DATETIME, @EndDate DATETIME'
                      ,@AccountId
                      ,@StartDate
                      ,@EndDate
END

Add your parameters in following fashion.

SqlParameter paramAcc = new SqlParameter("@AccountId", accountID);
paramAcc.DbType = DbType.Int32;
paramAcc.Direction = ParameterDirection.Input;
cmd.Parameters.Add(paramAcc);

if (from != null)
{
    SqlParameter paramSDate = new SqlParameter("@StartDate", from);
    paramSDate.DbType = DbType.DateTime;
    paramSDate.Direction = ParameterDirection.Input;
    cmd.Parameters.Add(paramSDate);
}

if (to != null)
{
    SqlParameter paramEDate = new SqlParameter("@EndDate", to);
    paramEDate.DbType = DbType.DateTime;
    paramEDate.Direction = ParameterDirection.Input;
    cmd.Parameters.Add(paramEDate);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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