Not able to get data from cursor in oracle - asp.net

I am trying to get data from oracle database using asp.net but I am not getting any output in cursor while data is present in table:
I am using following stored procedure:
CREATE OR REPLACE PROCEDURE branch_details
( startIndex in int
,pageSize in int
,isSearch in int
,byName in int
,dataDetail in varchar2
, p_cursor out sys_refcursor)
AS
BEGIN
IF isSearch=1 THEN
IF byName=1 THEN
OPEN p_cursor FOR
SELECT *
FROM (SELECT ROW_NUMBER() OVER(ORDER BY branch_id)
AS MyRows
, branch_id, branch_name
, branch_location, bm_name, bm_contact
, bm_email, is_active, max_ua
, (SELECT COUNT(branch_id)
FROM branch_info
WHERE branch_name LIKE
'%'|| dataDetail||'%')
AS RowNumber
FROM branch_info
WHERE branch_name LIKE '%'|| dataDetail||'%')
WHERE MyRows BETWEEN startIndex
AND startIndex+pageSize-1;
ELSE
OPEN p_cursor FOR
SELECT *
FROM (SELECT ROW_NUMBER() OVER(ORDER BY branch_id)
AS MyRows
, branch_id, branch_name, branch_location
, bm_name, bm_contact, bm_email, is_active
, max_ua
, (SELECT COUNT(branch_id)
FROM branch_info
WHERE branch_id LIKE
'%'|| dataDetail||'%')
As RowNumber
FROM branch_info
WHERE branch_id LIKE '%'|| dataDetail||'%')
WHERE MyRows BETWEEN startIndex
AND startIndex+pageSize-1;
END IF;
ELSE
OPEN p_cursor FOR
SELECT *
FROM (SELECT ROW_NUMBER() OVER(ORDER BY branch_id)
AS MyRows
, branch_id, branch_name, branch_location
, bm_name, bm_contact, bm_email
, is_active, max_ua
, (SELECT COUNT(branch_id)
FROM branch_info) AS RowNumber
FROM branch_info)
WHERE MyRows BETWEEN startIndex
AND startIndex+pageSize-1;
END IF;
END;
And using following asp.net code:
List<Paramarray> param = new List<Paramarray>();
param.Add(new Paramarray("#dataDetail", data));
param.Add(new Paramarray("#byName", id?"0":"1"));
param.Add(new Paramarray("#isSearch", isSearch?"1":"0"));
param.Add(new Paramarray("#startIndex", startIndex==1?startIndex.ToString():Convert.ToString(((startIndex-1)*pageSize)+1)));
param.Add(new Paramarray("#pageSize", pageSize.ToString()));
_command.Connection = _connection;
_command.CommandType = CommandType.StoredProcedure;
_command.CommandText = "branch_details";
foreach (Paramarray _param in param)
{
_parameter = new OracleParameter(_param.name,_param.value);
_command.Parameters.Add(_parameter);
}
_command.Parameters.Add("#p_cursor", OracleDbType.RefCursor).Direction = ParameterDirection.Output;
if (_connection.State != ConnectionState.Open) _connection.Open();
_dataReader = _command.ExecuteReader();
dt.Load(_dataReader);
if (_connection.State == ConnectionState.Open) _connection.Close();
My same code for another procedure is working fine and giving me output.
Please help me if I am wrong in my procedure or somewhere else. I am not able to figure the problem.

I am going to wager that your procedure is wrong. Your asp.net code looks fine and without more information it seems to me that the cursor is just not returning any data.
Have you unit tested the procedure or even just the cursor queries?

Related

How to separate (split) string with comma in SQL Server stored procedure

I have a checkboxlist. The selected (checked) items are stored in List<string> selected.
For example, value selected is monday,tuesday,thursday out of 7 days
I am converting List<> to a comma-separated string, i.e.
string a= "monday,tuesday,thursday"
Now, I am passing this value to a stored procedure as a string. I want to fire query like:
Select *
from tblx
where days = 'Monday' or days = 'Tuesday' or days = 'Thursday'`
My question is: how to separate string in the stored procedure?
If you pass the comma separated (any separator) string to store procedure and use in query so must need to spit that string and then you will use it.
Below have example:
DECLARE #str VARCHAR(500) = 'monday,tuesday,thursday'
CREATE TABLE #Temp (tDay VARCHAR(100))
WHILE LEN(#str) > 0
BEGIN
DECLARE #TDay VARCHAR(100)
IF CHARINDEX(',',#str) > 0
SET #TDay = SUBSTRING(#str,0,CHARINDEX(',',#str))
ELSE
BEGIN
SET #TDay = #str
SET #str = ''
END
INSERT INTO #Temp VALUES (#TDay)
SET #str = REPLACE(#str,#TDay + ',' , '')
END
SELECT *
FROM tblx
WHERE days IN (SELECT tDay FROM #Temp)
Try this:
CREATE FUNCTION [dbo].[ufnSplit] (#string NVARCHAR(MAX))
RETURNS #parsedString TABLE (id NVARCHAR(MAX))
AS
BEGIN
DECLARE #separator NCHAR(1)
SET #separator=','
DECLARE #position int
SET #position = 1
SET #string = #string + #separator
WHILE charindex(#separator,#string,#position) <> 0
BEGIN
INSERT into #parsedString
SELECT substring(#string, #position, charindex(#separator,#string,#position) - #position)
SET #position = charindex(#separator,#string,#position) + 1
END
RETURN
END
Then use this function,
Select *
from tblx
where days IN (SELECT id FROM [dbo].[ufnSplit]('monday,tuesday,thursday'))
try this
CREATE FUNCTION Split
(
#delimited nvarchar(max),
#delimiter nvarchar(100)
) RETURNS #t TABLE
(
-- Id column can be commented out, not required for sql splitting string
id int identity(1,1), -- I use this column for numbering splitted parts
val nvarchar(max)
)
AS
BEGIN
declare #xml xml
set #xml = N'<root><r>' + replace(#delimited,#delimiter,'</r><r>') + '</r></root>'
insert into #t(val)
select
r.value('.','varchar(max)') as item
from #xml.nodes('//root/r') as records(r)
RETURN
END
GO
usage:
select * from tblx where days in (select val from dbo.split('monday,tuesday,thursday',','))
I think you want this
SELECT * FROM tblx where days in ('Monday','Tuesday','Thursday')
you can get it like this:
var a = "monday,tuesday,thursday";
var sql = string.Format("Select * from tblx where days IN ('{0}')", string.Join("','",a.Split(new[] {','})));
I face the same problem, and i try all the way but not get expected solution. Finally i did like follow. Try it hope it will work...
create Function [dbo].[Split]
(
#RowData NVARCHAR(MAX),
#SplitOn NVARCHAR(5)
)
RETURNS #RtnValue TABLE
(
Id INT IDENTITY(1,1),
Data NVARCHAR(100)
)
AS
BEGIN
DECLARE #Cnt INT
SET #Cnt = 1
WHILE (Charindex(#SplitOn,#RowData)>0)
BEGIN
INSERT INTO #RtnValue (data)
SELECT Data = ltrim(rtrim(Substring(#RowData,1,Charindex(#SplitOn,#RowData)-1)))
SET #RowData = Substring(#RowData,Charindex(#SplitOn,#RowData)+1,len(#RowData))
SET #Cnt = #Cnt + 1
END
INSERT INTO #RtnValue (data)
SELECT Data = ltrim(rtrim(#RowData))
RETURN
END
And in the store procedure put the code like that.
select #ActualTarget= count(*) from UpdateVisitDetails where CreatedBy IN (SELECT [DATA] FROM [dbo].[Split](#AllDATS,',' ))
I have same problem. I tried this.. and this was properly run
ALTER FUNCTION [dbo].[Split]
(
#List varchar(max),
#SplitOn nvarchar(5)
)
RETURNS #RtnValue table
(
Id int identity(1,1),
Value nvarchar(max)
)
AS
BEGIN
IF (len(#List) <=0)
Begin
Return
End
While (Charindex(#SplitOn,#List)>0)
Begin
Insert Into #RtnValue (value)
Select
Value = ltrim(rtrim(Substring(#List,1,Charindex(#SplitOn,#List)-1)))
Set #List = Substring(#List,Charindex(#SplitOn,#List)+len(#SplitOn),len(#List))
End
Insert Into #RtnValue (Value)
Select Value = ltrim(rtrim(#List))
Return
END
Run :
SELECT * FROM dbo.Split('Apple,Banana,Mango',',')
Output:

SQL Server Count Occurrences of a value of colounns

Thank you for taking time to read this.
I have a ServiceDetails Table which have columns like
ID, ServiceID , ClientID... , Status ,IsFollowUp
and Services have
ID, Date , CityID, AreaID
Now when a service request is entered , its status is either 'pending', 'Completed','testing', or 'indeteriminent'.
Now end user wants a report that
City, Area , TotalServices , Total Completed without followup , Total Completed at First followup, Total Completed at 2nd followup ... , Total Completed at Fifth followup
I have Completed uptill now, Total Completed without followup but how do I calculate the Completed services followups count.
CREATE TABLE #TEMP#(
[ID] int PRIMARY KEY IDENTITY,
[Area] varchar(250),
[City] varchar(250),
[Total] int,
[WithoutFollowup] int,
[FirstFollowup] int,
[SecondFollowup] int,
[ThirdFollowup] int,
[FourthFollowup] int,
[FifthFollowup] int
);
DECLARE #AreaID AS bigint = 0
DECLARE #CityID AS bigint = 0
DECLARE #AreaName AS nvarchar(250) = ''
DECLARE #CityName AS nvarchar(250) = ''
DECLARE #VCCTDetailsID AS bigint = NULL, #ClientID AS bigint = NULL
,#TotalTests as int, #WithoutFollowup as int, #FirstFollowup as int,#SecondFollowup as int, #ThirdFollowup as int, #FourthFollowup as int, #FifthFollowup as int
,#Org as varchar(250),#City as varchar(250)
DECLARE cur CURSOR FOR
SELECT Areas.ID, Areas.Name, Cities.ID, Cities.CityName
FROM [dbo].[Areas]
INNER JOIN [dbo].[AreaCities] ON Areas.ID = AreaCities.AreaID
INNER JOIN [dbo].[Cities] ON AreaCities.CityID = Cities.ID
INNER JOIN [dbo].[States] ON States.ID = Cities.StateID
INNER JOIN [dbo].[Countries] ON Countries.ID = States.CountryID
WHERE [Areas].[IsActive] = 1
AND [Cities].[IsActive] = 1
AND [Areas].[CountryID] = 168
OPEN cur
FETCH NEXT FROM cur INTO #AreaID, #AreaName, #CityID, #CityName
WHILE ##FETCH_STATUS = 0
BEGIN
SET #Total = (
SELECT COUNT(1)
FROM [dbo].[ServiceDetails]
INNER JOIN [dbo].[Services] ON [ServiceDetails].[ServiceID] = [Services].[ID]
Where [ServiceDetails].[Status] !='Testing'
AND [ServiceDetails].[Status] !='Pending'
AND [Services].[AreaID] = #AreaID
AND [Services].[CityID] = #CityID
GROUP BY [Services].[AreaID],[Services].[CityID]
)
SET #WithoutFollowup = (
SELECT COUNT(1)
FROM [dbo].[ServiceDetails]
INNER JOIN [dbo].[Services] ON [ServiceDetails].[ServiceID] = [Services].[ID]
Where [ServiceDetails].[Status] !='completed'
AND [ServiceDetails].[IsFollowUp] = 'false'
AND [Services].[AreaID] = #AreaID
AND [Services].[CityID] = #CityID
GROUP BY [Services].[AreaID],[Services].[CityID]
)
SET #FirstFollowup = (
SELECT COUNT(1)
FROM [dbo].[ServiceDetails]
INNER JOIN [dbo].[Services] ON [ServiceDetails].[ServiceID] = [Services].[ID]
Where [ServiceDetails].[Status] !='completed'
AND [ServiceDetails].[IsFollowUp] = 'True'
GROUP BY [Services].[AreaID],[Services].[CityID]
)
INSERT #TEMP# ([Org],[City],[Total],[WithoutFollowup],[FirstFollowup],[SecondFollowup],[ThirdFollowup],[FourthFollowup],[FifthFollowup])
VALUES(#AreaName,#CityName,#Total,#WithoutFollowup,#FirstFollowup,#SecondFollowup,#ThirdFollowup,#FourthFollowup,#FifthFollowup);
FETCH NEXT FROM cur INTO #AreaID, #AreaName, #CityID, #CityName
END
CLOSE cur
DEALLOCATE cur
SELECT * FROM #TEMP#
DROP TABLE #TEMP#
I've accomplished this task using rownumbers and another temporary Table inside the cursor
INSERT INTO #Services#
SELECT ROW_NUMBER() OVER (ORDER BY [Services].[Date]) as 'RowNo',[ServiceDetails].* , [Services].[Date]
FROM [ServiceDetails]
INNER JOIN [Services] ON [Services].[ID] = [ServiceDetails].[VCCTsServiceID]
INNER JOIN [Clients] ON [Clients].[ID] = [ServiceDetails].[ClientID]
WHERE [Clients].[ID] LIKE #ClientID
ORDER BY [Services].[Date]
This #Services# is the exact replica of ServiceDetails table. Now we have all the services given to the client with rownumber and Date. It is sorted on date so we get the followups exactly when they are done. Now you can query what you want.
SET #TotalServices = ( SELECT COUNT(*) FROM #Services# )
SET #FirstSericeDate = (SELECT [#Services#].[Date] FROM #Services# WHERE [#Services#].[RowNo] = 1 )
SET #Status = (SELECT [#Services#].[Status] FROM #Services# WHERE [#Services#].[RowNo] = 1 )
SET #Date1 = (SELECT [#Services#].[Date] FROM #Services# WHERE [#Services#].[RowNo] = 2 )
SET #Status1 = (SELECT [#Services#].[Status] FROM #Services# WHERE [#Services#].[RowNo] = 2)
Then insert your variables into main temptable for reporting
INSERT #TEMP# ([RegNo], . . . [Status], Date1], [Status1] . .)
VALUES(#RegNo, . .. #Status, #Date1 , #Status1, . . );
TRUNCATE TABLE #Services#
FETCH NEXT FROM cur INTO #RegNo

How to return last identity value generated for a specific table in the current session and the current scope

I am inserting a row in Table1.
I am inserting the last Srno(identity) of this Table1 and some other values in Table2
I am doing all this in one stored procedure
CREATE PROCEDURE proc_test1
(
#MultipleImgsTvp AS testdbtype READONLY,
#ClaimDetailsTvp AS testdbtype1 READONLY
)
AS BEGIN
INSERT INTO dbo.Tbl_ClaimDetails (BranchRemark, BrMkrid, BrMkrdt, BAZClaimNo, HORemark, HoMkrid, hoMkrdt, ClaimType, ContactDetails, VendorName)
SELECT BranchRemark
, BrMkrid
, GETDATE()
, BAZClaimNo
, HORemark
, HoMkrid
, GETDATE()
, ClaimType
, ContactDetails
, VendorName
FROM #ClaimDetailsTvp
DECLARE #id INT = SCOPE_IDENTITY()
DECLARE #ClaimNo VARCHAR(25)
SET #ClaimNo = (
SELECT Em_Branchcdnew
FROM tbl_xyz
WHERE Em_empid = (SELECT BrMkrid FROM #ClaimDetailsTvp)
) + '/' + LEFT(CONVERT(VARCHAR, GETDATE(), 111), 8) + CONVERT(VARCHAR, #ID)
UPDATE Tbl_ClaimDetails
SET ClaimNo = #ClaimNo
WHERE Srno = #ID
----------
INSERT INTO Tbl_ClaimImages (img, id, imgname)
SELECT img
, id
, imgname
FROM #MultipleImgsTvp
----------
END
But i am always getting 0 in ID.
UPDATE
Tbl_ClaimDetails
SrNo(identity) | Remark | BrMkrdt | ...so on
i want to get the last inserted SrNo of Tbl_ClaimDetails
Shouldn't your final insert statement be:
INSERT INTO Tbl_ClaimImages (img, id, imgname)
SELECT img
, #id
, imgname
FROM #MultipleImgsTvp
Raj
If I understand you correctly, you can use the OUTPUT section of the query like so :
INSERT INTO dbo.Tbl_ClaimDetails (BranchRemark, BrMkrid, BrMkrdt, BAZClaimNo, HORemark, HoMkrid, hoMkrdt, ClaimType, ContactDetails, VendorName)
OUTPUT inserted.id INTO #ID
SELECT BranchRemark
, BrMkrid
, GETDATE()
, BAZClaimNo
, HORemark
, HoMkrid
, GETDATE()
, ClaimType
, ContactDetails
, VendorName
FROM #ClaimDetailsTvp
With the OUTPUT section, you can access the inserted row data by using inserted.column

Stored Procedure fails to see parameters or returns a convert data type error

I've run into a rather annoying problem which I cannot seem to get to the root of.
I've searched the internet for similar problems - and I've found a few unanswered in other forums - so I thought I'd give it a go here.
The following WebMethod of a webservice contacts a database, which works fine, and runs a stored procedure.
The problem is, that when I pass the parameters as single characters it tells me it cannot find either of the parameters and when I pass a full length "ean" parameter it tells me the following error message:
System.Data.OleDb.OleDbException: Error converting data type varchar to int.
at System.Data.OleDb.OleDbDataReader.ProcessResults(OleDbHResult hr)
at System.Data.OleDb.OleDbDataReader.NextResult()
at System.Data.OleDb.OleDbCommand.ExecuteReaderInternal(CommandBehavior behavior, String method)
at System.Data.OleDb.OleDbCommand.ExecuteReader(CommandBehavior behavior)
at System.Data.OleDb.OleDbCommand.ExecuteReader()
at Service.GetOthersRatings(Int32 personID, String ean)
And now here's the Webmethod:
[WebMethod(Description = "GetRatings")]
public string GetRatings(int personID, string ean)
{
string ratings = "";
OleDbConnection connection = new OleDbConnection(connectionString);
OleDbCommand command = new OleDbCommand("GetRatings", connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add("#personID",OleDbType.Integer,10).Value = personID;
command.Parameters.Add("#ean",OleDbType.VarChar,30).Value = ean;
try
{
connection.Open();
myReader = command.ExecuteReader();
if (myReader.HasRows)
{
while (myReader.Read())
{
ratings = myReader.GetString(0);
}
}
else
{
ratings = "Null";
}
}
catch (Exception e)
{
ratings = "Error - " + e.ToString();
}
finally
{
}
return ratings;
}
One thing that's worth mentioning is that if I remove the OUTPUT part of the SP, it runs fine down to and returns
ratings = "Null";
But seeing that I try to read a String from the reader, I don't see why it wouldn't work with a varchar output from the SP.
In the Database we have the corresponding Stored Procedure, which works fine if just executed in SQL Server Management Studio:
IF ( OBJECT_ID('GetRatings') IS NOT NULL )
DROP PROCEDURE GetRatings
GO
CREATE PROCEDURE GetRatings
#ratingschars varchar(36) = NULL OUTPUT,
#personID int,
#ean varchar(30)
AS
BEGIN TRAN
SET NOCOUNT ON;
BEGIN
DECLARE #pris varchar(2)
DECLARE #forventet varchar(2)
DECLARE #smag varchar(2)
DECLARE #count varchar(30)
IF EXISTS(SELECT * FROM feedback where personID = #personID AND ean = #ean)
BEGIN
SELECT #pris = (SELECT CAST(pris AS varchar(2)) FROM feedback where personID = #personID AND ean = #ean)
SELECT #forventet = (SELECT CAST(forventet AS varchar(2)) FROM feedback where personID = #personID AND ean = #ean)
SELECT #smag = (SELECT CAST(smag AS varchar(2)) FROM feedback where personID = #personID AND ean = #ean)
SELECT #ratingschars = #pris + #forventet + #smag
END
ELSE
BEGIN
SELECT #pris = (SELECT CAST(avg(pris) AS varchar(2)) FROM feedback WHERE ean = #ean)
SELECT #forventet += (SELECT CAST(avg(forventet) AS varchar(2)) FROM feedback WHERE ean = #ean)
SELECT #smag += (SELECT CAST(avg(smag) AS varchar(2)) FROM feedback WHERE ean = #ean)
SELECT #count += (SELECT CAST(count(*) AS varchar(30)) FROM feedback WHERE ean = #ean)
SELECT #ratingschars = #pris + #forventet + #smag + #count
END
END
COMMIT TRAN
Which I've tried to change to output of to int, with the same error results.
I'm stumped - I need help.
Stored-procedure has three parameters where as in your code, you've added only two parameters. So add a third parameter as OutPut type.
EDIT:
Stored Procedure:
ALTER PROCEDURE SampleProc
#no1 int,
#no2 int,
#result int OUTPUT
AS
set #result=#no1+#no2
RETURN
Code to execute the Stored-procedure:
cmd.CommandText = "SampleProc"
cmd.CommandType = CommandType.StoredProcedure
cmd.Connection = cn
Dim no1 as New OleDbParameter("#no1", OleDbType.Integer)
Dim no2 as New OleDbParameter("#no2", OleDbType.Integer)
Dim resultas New OleDbParameter("#result", OleDbType.Integer)
result.Direction = ParameterDirection.Output
no1.Value = 10
no2.Value = 20
cmd.Parameters.Add(no1)
cmd.Parameters.Add(no2)
cmd.Parameters.Add(result)
cn.Open()
cmd.ExecuteNonQuery()
cn.Close()
Dim returnResult as Integer
returnResult=CType(result.Value,Integer)
can you try the following?
command.Parameters.AddWithValue("#personID", personID);
command.Parameters.AddWithValue("#ean", ean);
Also, IF EXISTS(...) ... ELSE ... can be replaced with:
IF EXISTS(SELECT * FROM feedback where personID = #personID AND ean = #ean)
BEGIN
SELECT #ratingschars
= CAST(pris AS varchar(2))
+ CAST(forventet AS varchar(2))
+ CAST(smag AS varchar(2))
FROM feedback
WHERE personID = #personID
AND ean = #ean
END
ELSE
BEGIN
SELECT #ratingschars
= CAST(avg(pris) AS varchar(2)) --or STR
+ CAST(avg(forventet) AS varchar(2)) --or STR
+ CAST(avg(smag) AS varchar(2)) --or STR
+ CAST(count(*) AS varchar(11))
FROM feedback
WHERE ean = #ean
END
END
or
SELECT #ratingschars --Question: all these columns (pris, forventet, smag) are NOT NULL ?
= CAST(pris AS varchar(2))
+ CAST(forventet AS varchar(2))
+ CAST(smag AS varchar(2))
FROM feedback
WHERE personID = #personID
AND ean = #ean
IF #ratingschars IS NULL
BEGIN
SELECT #ratingschars
= CAST(avg(pris) AS varchar(2))
+ CAST(avg(forventet) AS varchar(2))
+ CAST(avg(smag) AS varchar(2))
+ CAST(count(*) AS varchar(30))
FROM feedback
WHERE ean = #ean
END

Asp.net(c#) Custom Paging With Stored Procedure - Bad Performance During Pagination

I have a asp:GridView with datasource like List
I added custom paging, using a procedure, when i use the procedure in MS SERVER Management
Studio its performance is fast, as soon as i try it in asp.net, performance is awful during
pagination.
The 1st step (when the gridview fills) is very fast, but when i am starting to paginate,
the performance kills, i am waiting 5-25 seconds for passing to the next page.
Dear all, what must i do to solve this problem, will you help me ?
HERE IS THE STORED PROCEDURE
CREATE PROCEDURE [sp_QS]
#startRowIndex INT,
#maximumRows INT,
#afterWhere NVARCHAR(MAX),
#sortBy NVARCHAR(MAX),
#totalRows INT OUT
AS
SET NOCOUNT ON;
DECLARE #P NVARCHAR(MAX), #Q1 NVARCHAR(MAX), #Q2 NVARCHAR(MAX)
DECLARE #first_id INT
SET #startRowIndex = (#startRowIndex - 1) * #maximumRows
SET #Q1 = 'query part 1'
SET #Q2 = 'query part 2'
IF #startRowIndex = 0
BEGIN
SET #startRowIndex = 1
END
SET ROWCOUNT #startRowIndex
SET #P = 'SET NOCOUNT ON; DECLARE #out INT SELECT #out = id FROM table1 ' + #Q2 + '
WHERE ' + #afterWhere + ' SELECT #out'
IF OBJECT_ID('tempdb..#t1','u') IS NOT NULL
BEGIN
DROP TABLE #t1
END
CREATE TABLE #t1 (col INT)
INSERT #t1 EXEC(#P)
SELECT #first_id = col FROM #t1
DROP TABLE #t1
--SELECT #first_id AS FFFF --PRINT #first_id
SET ROWCOUNT #maximumRows
SET #P = 'SET NOCOUNT ON;' + 'SELECT ' + #Q1 + ' FROM table ' + #Q2 + ' WHERE (id >=' +
CAST(#first_id AS NVARCHAR(60)) + ') AND (' + #afterWhere + ') ' + #sortBy
EXEC(#P)
SET ROWCOUNT 0
-- GET THE TOTAL ROWS
IF #startRowIndex = 1
BEGIN
SET #P = 'SET NOCOUNT ON;' + 'SELECT COUNT(id) FROM table1 ' + #Q2 + ' WHERE ' +
#afterWhere
IF OBJECT_ID('tempdb..#t2','u') IS NOT NULL
BEGIN
DROP TABLE #t2
END
CREATE TABLE #t2 (col INT)
INSERT #t2 EXEC (#P)
SELECT #totalRows = col FROM #t2
DROP TABLE #t2
SELECT #totalRows AS QueryResultRowCount
END
GO
AND HERE IS THE CODE IN ASP.NET(WITH C#)
private void BindData()
{
string connectionString = "Server=localhost;" +
"Database=Northwind;Trusted_Connection=true";
SqlConnection myConnection = new SqlConnection(connectionString);
SqlCommand myCommand = new SqlCommand("usp_GetProducts",
myConnection);
myCommand.CommandType = CommandType.StoredProcedure;
myCommand.Parameters.AddWithValue("#startRowIndex",
currentPageNumber);
myCommand.Parameters.AddWithValue("#maximumRows", PAGE_SIZE);
myCommand.Parameters.Add("#totalRows", SqlDbType.Int, 4);
myCommand.Parameters["#totalRows"].Direction =
ParameterDirection.Output;
SqlDataReader sqlReader = myCommand.ExecuteReader();
while(sqlReader.Read())
{
// filling List<> object to bind to gridview as datasource
}
...
}
I have to buttons 'next' and 'prvious', pressing these buttons, i am changing
currentPageNumber with + or - 1, calling BindData() method after it.
Thanks in advance
That's an SQL against the AdventureWorks database from SQL Server 2005 samples:
DECLARE
#FirstRow int,
#LastRow int,
#Sorting varchar(50);
Declare #SelectClause nvarchar(max),
#Params nvarchar(MAX);
SELECT #FirstRow = 1, #LastRow = 10;
SELECT #SelectClause = 'WITH CTE AS (
SELECT
ROW_NUMBER() OVER ( ORDER BY ' + COALESCE(#Sorting, 'SalesOrderID ASC') + ' ) AS RowNumber,
COUNT(*) OVER() AS TotalRows,
SalesOrderID,
OrderDate,
DueDate,
CASE OnlineOrderFlag WHEN 1 THEN ''Yes'' ELSE ''No'' END as OnlineOrderFlagString
FROM
Sales.SalesOrderHeader
WHERE
SubTotal > 100)
SELECT * FROM CTE WHERE RowNumber >= #FirstRow AND RowNumber < #LastRow',
#Params = '#FirstRow int, #LastRow int';
exec sp_executesql
#statement = #SelectClause,
#params = #Params,
#FirstRow = #FirstRow,
#LastRow = #LastRow;
After you have execute query you can fetch total rows value from first row if exists. Note, that if you must provide ability to sort by computed columns like the OnlineOrderFlagString, the query will become bit more complex:
DECLARE
#FirstRow int,
#LastRow int,
#Sorting varchar(50);
Declare #SelectClause nvarchar(max),
#Params nvarchar(MAX);
SELECT #FirstRow = 1, #LastRow = 10, #Sorting = 'OnlineOrderFlagString ASC'
SELECT #SelectClause = 'WITH CTE_1 AS (
SELECT
SalesOrderID,
OrderDate,
DueDate,
CASE OnlineOrderFlag WHEN 1 THEN ''Yes'' ELSE ''No'' END as OnlineOrderFlagString
FROM
Sales.SalesOrderHeader
WHERE
SubTotal > 100),
CTE_2 AS (
SELECT
ROW_NUMBER() OVER ( ORDER BY ' + COALESCE(#Sorting, 'SalesOrderID ASC') + ' ) AS RowNumber,
COUNT(*) OVER() AS TotalRows,
SalesOrderID,
OrderDate,
DueDate,
OnlineOrderFlagString
FROM
CTE_1
)
SELECT * FROM CTE_2 WHERE RowNumber >= #FirstRow AND RowNumber < #LastRow',
#Params = '#FirstRow int, #LastRow int';
exec sp_executesql
#statement = #SelectClause,
#params = #Params,
#FirstRow = #FirstRow,
#LastRow = #LastRow;

Resources