I have a stored procedure that I put together using the CLR. The basic idea is the have a query that can accept any number of values. I havent included the portion of the code that handles smalldatetime searches and I havent yet finished the logic to handle sql data type constraints but I have been working on paging using SQL's Row_Number(). The code below works but I havent been able to come up with a way to find out either how many pages the result set has or how many total rows in the result set. I thought there might be a way to use a procedure's Return Value but I can't figure out how that can be done when using CLR based procedures.
Any ideas on where to start would be appreciated.
public static void DynamicSearch(int rtype, string dfields, int pageSize, int pageIndex, string sortBy, int sortDirection) { //Search parameters received from .aspx in format fieldName|fieldType|searchValue //Multiple search parameter segments are delimited with ^ String[] searchParams = dfields.Split('^'); SqlPipe p; //create the query and sqlcommand string cmdstr = "SELECT * FROM (SELECT ROW_NUMBER() OVER (ORDER BY " + sortBy + " " + sortDirection.ToString().Replace("0", "ASC").Replace("1", "DESC") + ") AS Row, * FROM myFiles WHERE "; SqlCommand sCmd = new SqlCommand(); //build in the parameters to the query foreach (string param in searchParams) { //parse out the params and add to query String[] paramParts = param.Split('|'); string fieldName = paramParts[0].ToString(); string fieldType = paramParts[1].ToString(); string searchValue = paramParts[2].ToString(); searchValue = "%" + searchValue + "%"; sCmd.Parameters.AddWithValue("@" + fieldName, searchValue); cmdstr += "(" + fieldName + " LIKE @" + fieldName + ") AND "; } //paging logic int startRow = pageIndex * pageSize + 1; int endRow = startRow + (pageSize - 1); cmdstr = cmdstr + ") AS Rownumbers WHERE Row BETWEEN " + startRow + " AND " + endRow + ";"; //Tie off querystring cmdstr = cmdstr.Replace(" AND ) AS Rownumbers", ") AS Rownumbers"); //Apply querystring and run command sCmd.CommandText = cmdstr; p = SqlContext.Pipe; p.ExecuteAndSend(sCmd); }
![]() |
0 |
![]() |
Are you sure you needed CLR and dynamic SQL to handle many parameters?
For similar requirement we were using SQLWhereBuilder from Code Project.
http://www.codeproject.com/KB/custom-controls/SqlWhereBuilder.aspx
Beware of bugs in the above code; I have only proved it correct, not tried it.
(Donald Knuth)
![]() |
0 |
![]() |
Naom,
Your solution is definately more polished and I'll take a look to see if I can use it or something like it instead of a CLR solution. I'm wondering though, when paging through records is it faster to pass the whole result set to asp.net and page through it using some sort of asp.net paging solution or would it be faster to just use SQL to page the data and pass only one page of results at a time?
I guess the real problem I am having is that using ROW_NUMBER() to page on the SQL side, regardless of whether I use CLR or your solution, I would have to run the SELECT statement twice. I tried using @@ROWNUMBER like:
SELECT @@ROWCOUNT AS totalHits;
but I only get the number of rows that were returned for that page so when my page size is 10 totalHits is returned as 10 unless I run a second select using the same WHERE values in a second SELECT and then @@ROWCOUNT that resultset.
...if that makes sense.
Thanks for your input.
-Sam
![]() |
0 |
![]() |
Please see http://www.code-magazine.com/Article.aspx?quickid=0703041
Sorry, I am very busy right now for the longer answer, I'll answer from home tonight.
Beware of bugs in the above code; I have only proved it correct, not tried it.
(Donald Knuth)
![]() |
0 |
![]() |
Naom:
Please see http://www.code-magazine.com/Article.aspx?quickid=0703041
Sorry, I am very busy right now for the longer answer, I'll answer from home tonight.
Mr. Goff's use of CTEs looks like it will give me what I need to make it work. I tested it with something like:
CREATE PROCEDURE [dbo].[testGetMyFiles] AS BEGIN WITH SearchResults AS (SELECT *, ROW_NUMBER() OVER (ORDER BY LastName ASC) AS ResultsRow FROM myFiles WHERE FirstName LIKE '%an%') SELECT * FROM (SELECT SearchResults.*, (SELECT COUNT(*) FROM SearchResults) AS RecCount FROM SearchResults)SearchRes WHERE ResultsRow BETWEEN 10 and 20 END
Using this gives me the rows that I was looking for and two additional rows ResultsRow and RecCount which have the assigned row number and the total number of matches for the parameters supplied respectively. I can now use these values in these columns and come up with some paging logic.
If anyone else finds this thread, I ran across another post (http://weblogs.asp.net/scottgu/archive/2006/01/01/434314.aspx) that uses the Common Table Expressions that Mr. Goff's example uses. Both examples are using very large result sets so I'll head down this direction.
Thanks a lot for the direction Naom.
![]() |
0 |
![]() |
My pleasure. Don't forget to mark the responses, though :)
Beware of bugs in the above code; I have only proved it correct, not tried it.
(Donald Knuth)
![]() |
0 |
![]() |