Search code examples
c#replacedatareader

Dynamic seek for a string sql and replace in C#


I use a ADO DataReader to get rows from a sql server. As DataReader has no record count I need to get the record count myself. So in my case I want to place the original sql statement, which is passed to the class dynamic, in a subquery.

Example

SELECT 
      id, 
      title, 
      value 
FROM table 
WHERE id = 1234 
ORDER BY title

should be

SELECT COUNT(*) 
   FROM (
         SELECT id, 
               title,
               value 
        FROM table 
        WHERE id = 1234 
        ORDER BY title)t

In this case we need to modify the SQL statement because the syntax demands a TOP 100 PERCENT added to work propertly:

SELECT COUNT(*) 
FROM (SELECT TOP 100 PERCENT id, 
                     title, 
                     value 
              FROM table 
              WHERE id = 1234 
              ORDER BY title)t

So I did this:

int fromIndex = this.SQL.IndexOf("SELECT", 
                     StringComparison.CurrentCultureIgnoreCase);
String countSql = "SELECT TOP 100 PERCENT" + 
                   this.SQL.Substring(fromIndex + 6);
countSql = "SELECT COUNT(*) FROM (" + countSql + ")t";

But what if the original statement already has a TOP clause like

SELECT TOP 5 id, 
             title, 
             value 
 FROM table 
 WHERE id = 1234 
 ORDER BY title

or even worse

SELECT   TOP   5  
               id, 
               title, 
               value 
     FROM table 
     WHERE id = 1234 
     ORDER BY title

So my code needs to handle this.

BTW: If someone has a far more better approach to make a record count from any SQL statement this answer is welcomed as well!

EDIT To clarify my question. The link How to get number of rows using SqlDataReader in C# explains how to do it. I read that. My question is how to handle the incoming SQL statement to add TOP 100 PERCENT clause or not.


Solution

  • Just to clarify: the query is something that is dynamically passed in? And then you want to know how many rows were read by it? I believe as one comment suggests; you could add "select @@rowcount" to the end of the passed-in query; then back in C# use .NextResult to jump from the query results to your row count result.