DNN Forums

Ask questions about your website to get help learning DNN and help resolve issues.

DAL2 - How to count records?

Sort:
You are not authorized to post a reply.





Veteran Member





    Hi all,

    I need to count records in a module. I wrote a stored procedure:

    CREATE PROCEDURE dbo.dnn_CountOutdatedRecords
       @ModuleID int,
       @StartDate datetime
    AS
    BEGIN
       SET NOCOUNT ON
    
       SELECT
          COUNT(*)
       FROM
          dbo.dnn_Records
       WHERE
          ModuleID = @ModuleID
          AND StartDate <= @StartDate
    END
    
    

    In the controller I wrote the following code:

    public int OutdatedRecordsCount(int moduleID, DateTime startDate)
    {
       int outdatedRecordsCount;
       using (IDataContext ctx = DataContext.Instance())
       {
          outdatedRecordsCount = ctx.ExecuteScalar(System.Data.CommandType.StoredProcedure, "{databaseOwner}{objectQualifier}CountOutdatedRecords", new object[] { moduleID, startDate });
       }
       return outdatedRecordsCount;
    }
    
    

    This always returns 0 (zero), even if I get a number selected when I execute the stored procedure. I tried with an OUTPUT parameter:

    CREATE PROCEDURE dbo.dnn_CountOutdatedRecords
       @ModuleID int,
       @StartDate datetime,
       @OutdatedRecordsCount OUTPUT
    AS
    BEGIN
       SET NOCOUNT ON
    
       SELECT
          @OutdatedRecordsCount = COUNT(*)
       FROM
          dbo.dnn_Records
       WHERE
          ModuleID = @ModuleID
          AND StartDate <= @StartDate
    
       RETURN @OutdatedRecordsCount
    END
    
    

    And in the controller:

    public int OutdatedRecordsCount(int moduleID, DateTime startDate)
    {
       int outdatedRecordsCount = 0;
       using (IDataContext ctx = DataContext.Instance())
       {
          ctx.ExecuteScalar(System.Data.CommandType.StoredProcedure, "{databaseOwner}{objectQualifier}CountOutdatedRecords", new object[] { moduleID, startDate, outdatedRecordsCount });
       }
       return outdatedRecordsCount;
    }
    
    

    This fired an exception, "Null object cannot be converted to a value type'. I changed the controller to a text command:

    public int OutdatedRecordsCount(int moduleID, DateTime startDate)
    {
       int outdatedRecordsCount;
       using (IDataContext ctx = DataContext.Instance())
       {
          outdatedRecordsCount = ctx.ExecuteScalar(System.Data.CommandType.Text, "SELECT COUNT(*) FROM {databaseOwner}{objectQualifier}Records WHERE ModuleID = @0 AND StartDate <= @1", new object[] { moduleID, startDate });
       }
       return outdatedRecordsCount;
    }
    
    

    This also returns 0 (zero).

    Any idea how to get this done right?

    Happy DNNing!
    Michael

    Michael Tobisch
    DNN★MVP

    dnnWerk Austria
    DNN Connect





    Veteran Member





      Solved it.

      Instead of the stored procedure I created a function:

      CREATE FUNCTION dbo.dnn_f_CountOutdatedRecords
      (
         @ModuleID int,
         @StartDate datetime
      )
      RETURNS int
      AS
      BEGIN
         DECLARE @OutdatedRecordsCount int
      
         SELECT
            @OutdatedRecordsCount = COUNT(*)
         FROM
            dbo.dnn_Records
         WHERE
            ModuleID = @ModuleID
            AND StartDate <= @StartDate
      
         RETURN @OutdatedRecordsCount
      END
      GO
      
      

      In the controller I use the follwing code:

      public static int OutdatedRecordsCount(int moduleID, DateTime startDate)
      {
         int outdatedRecordsCount = 0;
         using (IDataContext ctx = DataContext.Instance())
         {
            outdatedRecordsCount = ctx.ExecuteScalar(System.Data.CommandType.Text, "SELECT {databaseOwner}{objectQualifier}f_CountOutdatedRecords(@0, @1)", new object[] { moduleID, startDate });
         }
         return outdatedRecordsCount;
      }
      
      

      Eh, voila!

      Happy DNNing!
      Michael

      Michael Tobisch
      DNN★MVP

      dnnWerk Austria
      DNN Connect





      Veteran Member





        Anyway, if someone could post an example (or write a blog) of how to work with stored procedures that return an output parameter in DAL2 - this would be interesting.

        Happy DNNing!
        Michael

        Michael Tobisch
        DNN★MVP

        dnnWerk Austria
        DNN Connect





        Advanced Member





          If I wanted to get a single value from a stored procedure, this is how I'd do it:

          
          CREATE OR ALTER PROCEDURE CountOutdatedRecords (
              @ModuleId int,
              @StartDate datetime
          )
          AS
          BEGIN
              SELECT @moduleId + DATEDIFF(ns, GETUTCDATE(), @StartDate)
          END
          GO
          

          From the SQL, just SELECT the value you want.

          
          protected int GetValue()
          {
              using (IDataContext ctx = DataContext.Instance())
              {
                  return ctx.ExecuteScalar&lt;int&gt;(
                      System.Data.CommandType.StoredProcedure, 
                      "{databaseOwner}{objectQualifier}CountOutdatedRecords", 
                      new object[] { ModuleConfiguration.ModuleID, DateTime.Now });
              }
          }
          

          Using ExecuteScalar will get that single value from the SELECT result set.

          If you need to use an OUTPUT parameter, this will work:

          
          CREATE OR ALTER PROCEDURE CountOutdatedRecords (
            @ModuleId int,
            @StartDate datetime,
            @OutdatedRecordsCount int OUTPUT
          )
          AS
          BEGIN
              SELECT @moduleId + DATEDIFF(ns, GETUTCDATE(), @StartDate);
              SET @OutdatedRecordsCount = 123;
          END
          GO
          
          protected int GetOutputValue()
          {
              using (IDataContext ctx = DataContext.Instance())
              {
                  var count = new SqlParameter("@OutdatedRecordsCount", SqlDbType.Int) 
                      { 
                          Direction = ParameterDirection.Output 
                      };
                  ctx.Execute(
                      CommandType.StoredProcedure, 
                      "{databaseOwner}{objectQualifier}CountOutdatedRecords", 
                      new SqlParameter("@ModuleId", ModuleConfiguration.ModuleID), 
                      new SqlParameter("@StartDate", DateTime.Now),
                      count);
          
                  return (int)theResult.Value;
              }
          }

          Hope it helps!

          DNN partner specializing in custom, enterprise DNN development https://engagesoftware.com/showcase





          Veteran Member





            Thanks Brian, I'll try that.

            Happy DNNing!
            Michael

            Michael Tobisch
            DNN★MVP

            dnnWerk Austria
            DNN Connect
            You are not authorized to post a reply.

            These Forums are dedicated to the discussion of DNN Platform.

            For the benefit of the community and to protect the integrity of the ecosystem, please observe the following posting guidelines:

            1. If you have (suspected) security issues, please DO NOT post them in the forums but instead follow the official DNN security policy
            2. No Advertising. This includes the promotion of commercial and non-commercial products or services which are not directly related to DNN.
            3. No vendor trolling / poaching. If someone posts about a vendor issue, allow the vendor or other customers to respond. Any post that looks like trolling / poaching will be removed.
            4. Discussion or promotion of DNN Platform product releases under a different brand name are strictly prohibited.
            5. No Flaming or Trolling.
            6. No Profanity, Racism, or Prejudice.
            7. Site Moderators have the final word on approving / removing a thread or post or comment.
            8. English language posting only, please.

            Would you like to help us?

            Awesome! Simply post in the forums using the link below and we'll get you started.

            Get Involved