DNN Forums

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

DAL2 - How to count records?

 4 Replies
 0 Subscribed to this topic
 26 Subscribed to this forum
Sort:
Author
Messages
Veteran Member
Posts: 1182
Veteran Member
MVP
MVP
You're an MVP!

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

DNN Connect
Veteran Member
Posts: 1182
Veteran Member
MVP
MVP
You're an MVP!

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

DNN Connect
Veteran Member
Posts: 1182
Veteran Member
MVP
MVP
You're an MVP!
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

DNN Connect
Advanced Member
Posts: 159
Advanced Member
MVP
MVP
You're an MVP!

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

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

From the SQL, just <code>SELECT</code> the value you want.

<code>
protected int GetValue()
{
    using (IDataContext ctx = DataContext.Instance())
    {
        return ctx.ExecuteScalar<int><int>(
            System.Data.CommandType.StoredProcedure, 
            "{databaseOwner}{objectQualifier}CountOutdatedRecords", 
            new object&#91;&#93; { ModuleConfiguration.ModuleID, DateTime.Now });
    }
}
</int></code>

Using <code>ExecuteScalar</code> will get that single value from the <code>SELECT</code> result set.

If you need to use an <code>OUTPUT</code> parameter, this will work:

<code>
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</code>
<code>
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;
    }
}</code>

Hope it helps!

Veteran Member
Posts: 1182
Veteran Member
MVP
MVP
You're an MVP!
Thanks Brian, I'll try that.

Happy DNNing!
Michael

Michael Tobisch
DNN★MVP

DNN Connect

These Forums are for the discussion of the open source CMS DNN platform and ecosystem.

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