Catch the sp_executesql table Result - asp.net

I Have Stored Procedure by using sp_executesql:
USE [databasedevelopment]
GO
/****** Object: StoredProcedure [dbo].[SearchPaymentDev] Script Date: 06/03/2013 16:42:49 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER Procedure [dbo].[SearchPaymentDev]
#PayAccountin as varchar(10),
#PayCustNamein as varchar(30),
#PayAmountin as int,
#PayAmountPaidin as int,
#PayResponsein as char (2),
#PayRefNoin as varchar (120),
#PayScreenTextin as varchar (100),
#PayReceiptTextin as varchar (350),
#PayDatetimein as varchar(50),
#PayBankCodein as varchar (6)
AS
Set NoCount ON
Declare #SQLQuery AS NVarchar(4000)
Declare #ParamDefinition AS NVarchar(2000)
Set #SQLQuery = 'Select * From payment where PayId is not null '
If #PayAccountin Is Not Null
Set #SQLQuery = #SQLQuery + ' And (PayAccount LIKE ''%'' + #PayAccountin + ''%'')'
If #PayCustNamein Is Not Null
Set #SQLQuery = #SQLQuery + ' And (PayCustName LIKE ''%'' + #PayCustNamein + ''%'')'
If #PayAmountin Is Not Null
Set #SQLQuery = #SQLQuery + ' And (PayAmount LIKE ''%'' + #PayAmountin + ''%'')'
If #PayAmountPaidin Is Not Null
Set #SQLQuery = #SQLQuery + ' And (PayAmountPaid LIKE ''%'' + #PayAmountPaidin + ''%'')'
If #PayResponsein is Not Null
Set #SQLQuery = #SQLQuery + ' And (PayResponse LIKE ''%'' + #PayResponsein + ''%'')'
If #PayRefNoin is Not Null
Set #SQLQuery = #SQLQuery + ' And (PayRefNo LIKE ''%'' + #PayRefNoin + ''%'')'
If #PayBankCodein is Not Null
Set #SQLQuery = #SQLQuery + ' And (PayBankCode LIKE ''%'' + #PayAccountin + ''%'')'
If #PayDatetimein is Not Null
Set #SQLQuery = #SQLQuery + ' And (cast(PayDatetime as date) = ( select convert(date , #PayDatetimein , 103)))'
Set #ParamDefinition =
'#PayAccountin as varchar(10),
#PayCustNamein as varchar(30),
#PayAmountin as int,
#PayAmountPaidin as int,
#PayResponsein as char (2),
#PayRefNoin as varchar (120),
#PayBankCodein as varchar (6),
#PayDatetimein as varchar(50)'
Execute sp_Executesql
#SQLQuery,
#ParamDefinition,
#PayAccountin,
#PayCustNamein,
#PayAmountin,
#PayAmountPaidin,
#PayResponsein,
#PayRefNoin,
#PayBankCodein,
#PayDatetimein
If ##ERROR <> 0 GoTo ErrorHandler
Set NoCount OFF
Return(0)
ErrorHandler:
Return(##ERROR)
Right now i use the stored procedure on vb.net code behind and get the data as datatable and process on VB.net Code behind.
but now I Want to get the table result query and progress to the same stored procedure to change some of the field value, is it possible to catch the table first on the stored procedure, change the value and give output to be used on vb.net ?
thanks for your help.

Try this one -
ALTER PROCEDURE [dbo].[SearchPayment]
#PayAccountin AS VARCHAR(10),
#PayCustNamein AS VARCHAR(30),
#PayAmountin AS INT,
#PayAmountPaidin AS INT,
#PayResponsein AS CHAR (2),
#PayRefNoin AS VARCHAR (120),
#PayScreenTextin AS VARCHAR (100),
#PayReceiptTextin AS VARCHAR (350),
#PayDatetimein AS VARCHAR(50),
#PayBankCodein AS VARCHAR (6)
AS BEGIN
SET NOCOUNT ON
SET XACT_ABORT ON
DECLARE #OwnTran BIT
SET #OwnTran = 0
IF ##TRANCOUNT = 0
BEGIN
SET #OwnTran = 1
BEGIN TRAN
END
BEGIN TRY
DECLARE #SQLQuery NVARCHAR(4000)
SELECT #SQLQuery = '
IF OBJECT_ID (N''tempdb.dbo.##test'') IS NOT NULL
DROP TABLE ##test
SELECT *
INTO ##test
FROM payment
WHERE PayId is not null '
+ ISNULL(' And (PayAccount LIKE ''%''' + #PayAccountin + '''%'')', '')
+ ISNULL(' And (PayCustName LIKE ''%''' + #PayCustNamein + '''%'')', '')
+ ISNULL(' And (PayAmount LIKE =' + CAST(#PayAmountin AS VARCHAR(5)) + ')', '')
+ ISNULL(' And (PayAmountPaid =' + CAST(#PayAmountPaidin AS VARCHAR(5)) + ')', '')
+ ISNULL(' And (PayResponse LIKE ''%''' + #PayResponsein + '''%'')', '')
+ ISNULL(' And (PayRefNo LIKE ''%''' + #PayRefNoin + '''%'')', '')
+ ISNULL(' And (PayBankCode LIKE ''%''' + #PayAccountin + '''%'')', '')
+ ISNULL(' And (cast(PayDatetime as date) = convert(date, #PayDatetimein , 103))', '')
EXEC sys.sp_Executesql #SQLQuery
END TRY
BEGIN CATCH
IF ##TRANCOUNT > 0
ROLLBACK TRAN
END CATCH
IF #OwnTran = 1
AND ##TRANCOUNT > 0
BEGIN
COMMIT TRAN
END
END

Related

SpyProcedure does not support User-defined table type

Solved it (hopefully!)
I have a user-defined table data type used as a parameter in a stored procedure.
I did a spy on it and it throws an error like the this:
A column cannot be of a user-defined table type.[16,1]{,1}
Is it not supported? If not, I am interested on how anyone did it - I mean spy a stored procedure similar to my case.
My db server is SQL2008 R2.
Below is the sample code to replicate it:
CREATE TYPE [dbo].[UserDefinedTableType] AS TABLE
(
[col1] INT NULL
,[col2] NVARCHAR(MAX) NULL
)
GO
CREATE PROCEDURE dbo.Bar
#ItemsToProcess UserDefinedTableType READONLY
AS
GO
CREATE PROCEDURE dbo.Foo
#ItemsToProcess UserDefinedTableType READONLY
AS
EXEC dbo.Bar #ItemsToProcess = #ItemsToProcess
GO
CREATE PROCEDURE [testDatabase].[test spy stored procedure using user-defined table type]
AS
DECLARE #items AS UserDefinedTableType
EXEC tSQLt.SpyProcedure 'dbo.Bar';
EXEC [dbo].[Foo] #ItemsToProcess = #items;
GO
EXEC tSQLt.Run '[testDatabase].[test spy stored procedure using user-defined table type]'
Hacked code below.
I've marked my changes. The goal was to query values from a table-valued parameter as XML. Note: The code is not yet thoroughly tested.
---Build+
CREATE PROCEDURE tSQLt.Private_CreateProcedureSpy
#ProcedureObjectId INT,
#OriginalProcedureName NVARCHAR(MAX),
#LogTableName NVARCHAR(MAX),
#CommandToExecute NVARCHAR(MAX) = NULL
AS
BEGIN
DECLARE #Cmd NVARCHAR(MAX);
DECLARE #ProcParmList NVARCHAR(MAX),
#TableColList NVARCHAR(MAX),
#ProcParmTypeList NVARCHAR(MAX),
#TableColTypeList NVARCHAR(MAX);
DECLARE #Seperator CHAR(1),
#ProcParmTypeListSeparater CHAR(1),
#ParamName sysname,
#TypeName sysname,
#IsOutput BIT,
/*>>>*/ #IsCursorRef BIT,
/*>>>*/ #IsTableType BIT;
SELECT #Seperator = '', #ProcParmTypeListSeparater = '',
#ProcParmList = '', #TableColList = '', #ProcParmTypeList = '', #TableColTypeList = '';
DECLARE Parameters CURSOR FOR
SELECT p.name, t.TypeName, is_output, is_cursor_ref, tp.is_table_type
FROM sys.parameters p CROSS APPLY tSQLt.Private_GetFullTypeName(p.user_type_id,p.max_length,p.precision,p.scale,NULL) t
/*>>>*/ INNER JOIN sys.types tp
/*>>>*/ ON p.user_type_id = tp.user_type_id
WHERE object_id = #ProcedureObjectId;
OPEN Parameters;
/*>>>*/ FETCH NEXT FROM Parameters INTO #ParamName, #TypeName, #IsOutput, #IsCursorRef, #IsTableType;
WHILE (##FETCH_STATUS = 0)
BEGIN
IF #IsCursorRef = 0
BEGIN
SELECT #ProcParmList = #ProcParmList + #Seperator +
CASE WHEN #IsTableType = 1
/*>>>*/ THEN '(SELECT * FROM ' + #ParamName + ' for xml path(''''))'
ELSE
#ParamName
END
,
#TableColList = #TableColList + #Seperator + '[' + STUFF(#ParamName,1,1,'') + ']',
#ProcParmTypeList = #ProcParmTypeList
+ #ProcParmTypeListSeparater
+ #ParamName
+ ' '
+ #TypeName
/*>>>*/ + CASE WHEN #IsTableType = 1 THEN ' READONLY ' ELSE ' = NULL ' END
+ CASE WHEN #IsOutput = 1 THEN ' OUT' ELSE '' END,
#TableColTypeList = #TableColTypeList + ',[' + STUFF(#ParamName,1,1,'') + '] ' +
/*>>>*/ CASE WHEN #IsTableType = 1 -- If parameter is a user-defined table type.
/*>>>*/ THEN 'xml'
WHEN #TypeName LIKE '%nchar%'
OR #TypeName LIKE '%nvarchar%'
THEN 'nvarchar(MAX)'
WHEN #TypeName LIKE '%char%'
THEN 'varchar(MAX)'
ELSE #TypeName
END + ' NULL';
SELECT #Seperator = ',';
SELECT #ProcParmTypeListSeparater = ',';
END
ELSE
BEGIN
SELECT #ProcParmTypeList = #ProcParmTypeListSeparater + #ParamName + ' CURSOR VARYING OUTPUT';
SELECT #ProcParmTypeListSeparater = ',';
END;
/*>>>*/ FETCH NEXT FROM Parameters INTO #ParamName, #TypeName, #IsOutput, #IsCursorRef, #IsTableType;
END;
CLOSE Parameters;
DEALLOCATE Parameters;
DECLARE #InsertStmt NVARCHAR(MAX);
SELECT #InsertStmt = 'INSERT INTO ' + #LogTableName +
CASE WHEN #TableColList = '' THEN ' DEFAULT VALUES'
ELSE ' (' + #TableColList + ') SELECT ' + #ProcParmList
END + ';';
SELECT #Cmd = 'CREATE TABLE ' + #LogTableName + ' (_id_ int IDENTITY(1,1) PRIMARY KEY CLUSTERED ' + #TableColTypeList + ');';
EXEC(#Cmd);
SELECT #Cmd = 'CREATE PROCEDURE ' + #OriginalProcedureName + ' ' + #ProcParmTypeList +
' AS BEGIN ' +
#InsertStmt +
ISNULL(#CommandToExecute, '') + ';' +
' END;';
EXEC(#Cmd);
RETURN 0;
END;
---Build-

Set Where Parameter Dynamically on stored procedure

I have a stored procedure to search the data from database with parameter like this :
CREATE PROCEDURE [dbo].[Rintis_SearchPayment]
-- Add the parameters for the stored procedure here
#payIDin as int,
#PayAccountin as varchar(10),
#PayCustNamein as varchar(30),
#PayAmountin as int,
#PayAmountPaidin as int,
#PayResponsein as char (2),
#PayRefNoin as varchar (120),
#PayScreenTextin as varchar (100),
#PayReceiptTextin as varchar (350),
#PayDatetimein as datetime,
#PayBankCodein as varchar (6),
#payIDou as int,
#PayAccountou as varchar(10),
#PayCustNameou as varchar(30),
#PayAmountou as int,
#PayAmountPaidou as int,
#PayResponseou as char (2),
#PayRefNoou as varchar (120),
#PayScreenTextou as varchar (100),
#PayReceiptTextou as varchar (350),
#PayDatetimeou as datetime,
#PayBankCodeouin as varchar (6)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
select #payIDou = PayId ,
#PayAccountou = PayAccount,
#PayCustNameou = PayCustName,
#PayAmountou = PayAmount,
#PayAmountPaidou = PayAmountPaid,
#PayResponseou= PayResponse,
#PayRefNoou= PayRefNo,
#PayScreenTextou= PayScreenText,
#PayReceiptTextou= PayReceiptText,
#PayDatetimeou= PayDatetime,
#PayBankCodeouin= PayBankCode
from Payment
where PayId is not null AND
PayAccount like '%'+ISNULL((#PayAccountin),'')+'%' AND
PayCustName LIKE '%'+ISNULL((#PayAccountin),'')+'%' AND
PayAmount LIKE '%'+ISNULL((#PayAccountin),'')+'%' AND
PayAmountPaid LIKE '%'+ISNULL((#PayAccountin),'')+'%' AND
PayResponse LIKE '%'+ISNULL((#PayAccountin),'')+'%' AND
PayRefNo LIKE '%'+ISNULL((#PayAccountin),'')+'%' AND
cast(PayDatetime as date) = ( select convert(date , ''+ISNULL((#PayAccountin),'')+'', 103)) order by PayDatetime DESC
select #payIDou
-- Insert statements for procedure here
END
but when I execute it I didn't give value, cause I know some like statement is incorrect, so it'll never give the return value.
At first I do the query like this on my vb .net :
Public Function SearchPayment(ByVal PayAccount As String, ByVal PayCustName As String, ByVal PayAmount As String, ByVal PayAmountPaid As String, ByVal PayResponse As String, ByVal PayRefNo As String, ByVal PayDatetime As String) As Boolean
Dim strsql As String = " select top 100 * from Payment where PayId is not null "
If PayAccount <> "" Then
strsql &= "and PayAccount like '%" & PayAccount & "%'"
End If
If PayCustName <> "" Then
strsql &= "and PayCustName like '%" & PayCustName & "%'"
End If
If PayAmount <> "" Then
strsql &= "and PayAmount like '%" & PayAmount & "%'"
End If
'' add PayAmountPaid
If PayAmountPaid <> "" Then
strsql &= "and PayAmountPaid like '%" & PayAmountPaid & "%'"
End If
If PayResponse <> "" Then
strsql &= "and PayResponse like '%" & PayResponse & "%'"
End If
'' add PayRefNo
If PayRefNo <> "" Then
strsql &= "and PayRefNo like '%" & PayRefNo & "%'"
End If
If PayDatetime <> "" Then
''select * from Inquiry where InquiryId is not null and cast(InquiryDate as date) = ( select convert(date ,'7/05/2013' , 103) )
strsql &= "and cast(PayDatetime as date) = ( select convert(date , '" & PayDatetime & "', 103)) "
End If
strsql &= "order by PayDatetime DESC"
Return runQuery(strsql)
End Function
Is it possible to add Where parameter by checking the input value first like I did on my vb.net ?
You can do this:
(#PayAccountin IS NULL OR
PayAccount like '%'+ISNULL((#PayAccountin),'')+'%') AND
If the parameter is null it will be true and will ignore the condition
Possible this be helpful for you -
CREATE PROCEDURE [dbo].[Rintis_SearchPayment]
#payIDin AS INT,
...
AS
BEGIN
SET NOCOUNT ON;
SELECT #payIDou = PayId ,
#PayAccountou = PayAccount,
#PayCustNameou = PayCustName,
#PayAmountou = PayAmount,
#PayAmountPaidou = PayAmountPaid,
#PayResponseou= PayResponse,
#PayRefNoou= PayRefNo,
#PayScreenTextou= PayScreenText,
#PayReceiptTextou= PayReceiptText,
#PayDatetimeou= PayDatetime,
#PayBankCodeouin= PayBankCode
FROM dbo.Payment
WHERE PayId IS NOT NULL
AND (
#PayAccountin IS NULL
OR
(
PayAccount LIKE '%' + #PayAccountin + '%'
AND PayCustName LIKE '%' + #PayAccountin + '%'
AND PayAmount LIKE '%'+ #PayAccountin +'%'
AND PayAmountPaid LIKE '%' + #PayAccountin +'%'
AND PayResponse LIKE '%'+ #PayAccountin + '%'
AND PayRefNo LIKE '%'+ #PayAccountin + '%'
)
)
AND (
#PayAccountin IS NULL
OR
CAST(PayDatetime AS DATE) = CONVERT(DATE , #PayAccountin, 103)
)
ORDER BY PayDatetime DESC
SELECT #payIDou
END
If you can change the stored procedure then the simplest solution would be to add the IS NULL check in the WHERE clause. Somethin like:
select #payIDou = PayId ,
#PayAccountou = PayAccount,
#PayCustNameou = PayCustName,
#PayAmountou = PayAmount,
#PayAmountPaidou = PayAmountPaid,
#PayResponseou= PayResponse,
#PayRefNoou= PayRefNo,
#PayScreenTextou= PayScreenText,
#PayReceiptTextou= PayReceiptText,
#PayDatetimeou= PayDatetime,
#PayBankCodeouin= PayBankCode
from Payment
where PayId is not null AND
((PayAccount like '%'+ #PayAccountin+'%') OR #PayAccountin IS NULL) AND
((PayCustName LIKE '%'+ #PayAccountin+'%') OR #PayAccountin IS NULL) AND... //the rest of your WHERE clause
This will effectively ignore the arguments that are passed as NULL.
Hope i understood your question correctly.
Thank You For your Respon, but i found another solution, using sp_Executesql and is more effective :
Create Procedure SearchPaymentDev
#PayAccountin as varchar(10),
#PayCustNamein as varchar(30),
#PayAmountin as int,
#PayAmountPaidin as int,
#PayResponsein as char (2),
#PayRefNoin as varchar (120),
#PayScreenTextin as varchar (100),
#PayReceiptTextin as varchar (350),
#PayDatetimein as datetime,
#PayBankCodein as varchar (6),
AS
Set NoCount ON
/* Variable Declaration */
Declare #SQLQuery AS NVarchar(4000)
Declare #ParamDefinition AS NVarchar(2000)
/* Build the Transact-SQL String with the input parameters */
Set #SQLQuery = 'Select * From payment where PayId is not null '
/* check for the condition and build the WHERE clause accordingly */
If #PayAccountin Is Not Null
Set #SQLQuery = #SQLQuery + ' And (PayAccount = #PayAccountin)'
If #PayCustNamein Is Not Null
Set #SQLQuery = #SQLQuery + ' And (PayCustName = #PayCustNamein)'
If #PayAmountin Is Not Null
Set #SQLQuery = #SQLQuery + ' And (PayAmount = #PayAmountin)'
If #PayAmountPaidin Is Not Null
Set #SQLQuery = #SQLQuery + ' And (PayAmountPaid = #PayAmountPaidin)'
--If (#StartDate Is Not Null) AND (#EndDate Is Not Null)
-- Set #SQLQuery = #SQLQuery + ' And (JoiningDate
-- BETWEEN #StartDate AND #EndDate)'
/* Specify Parameter Format for all input parameters included
in the stmt */
Set #ParamDefinition = '#PayAccountin as varchar(10),
#PayCustNamein as varchar(30),
#PayAmountin as int,
#PayAmountPaidin as int'
/* Execute the Transact-SQL String with all parameter value's
Using sp_executesql Command */
Execute sp_Executesql #SQLQuery,
#ParamDefinition,
#PayAccountin,
#PayCustNamein,
#PayAmountin,
#PayAmountPaidin
If ##ERROR <> 0 GoTo ErrorHandler
Set NoCount OFF
Return(0)
ErrorHandler:
Return(##ERROR)
GO

sql create table with stored procedure with optional parameters

I am writing a report based on parameters, utilizing a sql stored procedure. Problem is there are several 'optional' parameters, where the user can choose a value, or ignore that parameter altogether. I need to use the stored proc as a dataset in asp.net report. Only way I thought of doing it is to create a table from the results. But I'm clueless.
How do I turn this into a 'create table' stored proc?
Any assistance is greatly appreciated.
Cindy
This is what I have so far -
ALTER PROCEDURE [dbo].[rspSCL]
-- Add the parameters for the stored procedure here
(#year as int,
#RRID as int,
#State as nchar(2),
#Sub as varchar(75),
#app as int,
#sprayed as int,
#subcontracted as int,
#thirdapp as bit)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
DECLARE #SQL as varchar(4000)
DECLARE #SUBQ AS varchar(400)
--what fields need to be seen
SET #SQL = 'SELECT C.CRID, C.DOT, C.RR, C.Pref, C.MP, C.Division, C.Subdivision,C.City, C.Street,
C.State, C.County, C.RestrictedCounty, C.Remarks, C.SpecialInstructions, C.Route, C.ThirdAppRequired,
C.MainTrks, C.OtherTrks, C.OnSpur, C.MaxSpeed, C.SubContracted, C.FenceEncroachment, C.Lat, C.Long,
C.PropertyType, C.WarningDevice,C.Surface, C.ROWNE, C.ROWNW, C.ROWSE, C.ROWSW, C.ROWWidth, C.ExtNE,
C.ExtNW, C.ExtSE, C.ExtSW, C.TempActive, A.Spray, A.ContractYear'
SET #SUBQ =
CASE WHEN #app = 1 THEN
'FROM Crossings LEFT OUTER JOIN
(select A.CRID, A.spray FROM ApplicationData A
WHERE A.ContractYear = ' + CAST( #year AS varchar(4)) + ') as APPS
ON Crossings.CRID = APPS.CRID'
WHEN #app = 2 THEN
'FROM Crossings inner join
(SELECT crid, C,OUNT(APPID)as count
from ApplicationData
where ContractYear = ' + CAST( #year AS varchar(4)) + '
group by CRID) as APPS
ON Crossings.CRID = APPS.CRID
WHERE Crossings.RR = '+ CAST( #RRID AS varchar(4)) + '
and crossings.state = '+ #state + '
and count = 1'
when #app = 3 THEN
'FROM Crossings inner join
(SELECT crid, COUNT(APPID)as count
from ApplicationData
where ContractYear = ' + CAST( #year AS varchar(4)) + '
group by CRID) as APPS
ON Crossings.CRID = APPS.CRID
WHERE Crossings.RR = '+ CAST( #RRID AS varchar(4)) + '
and crossings.state = '+ #state + '
and count = 2'
ELSE ''
END
--add the FROM to the query
SET #SQL = #SQL + #SUBQ
--add the subdivision to the where statement
If #Sub != 'ALL'
SET #SQL = #SQL + 'AND (C.Subdivision = ' + #Sub + ')'
ELSE
SET #SQL = #SQL
--add sprayed to where
DECLARE #S as varchar(100)
SET #S =
CASE WHEN #sprayed = 1 THEN
'AND (A.sprayed = 1)'
WHEN #sprayed = 0 THEN
'AND (A.sprayed = 0)'
ELSE
''
END
SET #SQL = #SQL + #S
--add subcontracted to where
DECLARE #C as varchar (100)
SET #C =
CASE WHEN #subcontracted = 0 THEN
'AND (C.subcontracted = 0)'
WHEN #subcontracted = 1 THEN
'AND (C.subcontracted = 1)'
ELSE
''
END
SET #SQL = #SQL + #C
IF #thirdapp = 1
SET #SQL = #SQL + 'AND (C.ThirdAppRequired = 1)'
ELSE
SET #SQL = #SQL
END

Operand data type varchar is invalid for sum operator - Procedure Error Correction

I am using SQL Server - 2005...
ALTER Proc [dbo].[ExamResult] (#Course_Id varchar(100), #Semester varchar(10))
as
begin
declare #subjname varchar(100)
declare #subjects varchar(7000)
declare #subjectsselection varchar(7000)
declare #SumSelection varchar(7000)
declare #NoOfSubjects int
set #NoOfSubjects = 0
set #subjects = ''
set #subjectsselection = ''
set #SumSelection = ''
DECLARE subject_cursor CURSOR
FOR SELECT distinct Subject_Name FROM Exam_Result where course_id = #Course_Id And Semester = #Semester
OPEN subject_cursor
FETCH NEXT FROM subject_cursor
INTO #subjname
WHILE ##FETCH_STATUS = 0
BEGIN
set #subjects = #subjects + '[' + #subjname + '],'
set #subjectsselection = #subjectsselection + 'Sum(Isnull([' + #subjname + '],0)) As [' + #subjname + '],'
set #SumSelection = #SumSelection + 'Sum(Isnull([' + #subjname + '],0))+'
set #NoOfSubjects = #NoOfSubjects + 1
FETCH NEXT FROM subject_cursor
INTO #subjname
End
CLOSE subject_cursor;
DEALLOCATE subject_cursor;
select #subjects = LEFT(#subjects, LEN(#subjects) - 1)
select #subjectsselection = LEFT(#subjectsselection, LEN(#subjectsselection) - 1)
select #SumSelection = LEFT(#SumSelection, LEN(#SumSelection) - 1)
print #subjects
print #subjectsselection
print #SumSelection
declare #query nvarchar(4000)
set #query = 'select S.Enroll_Number, pvt.Student_Name, pvt.Course_Id, pvt.Semester, ' + #subjectsselection + ','
set #query = #query + 'Exam_Type,' + #SumSelection + ' As Grand_Total, '
set #query = #query + '(' + #SumSelection + ')' + '/' + convert(varchar(10),#NoOfSubjects) + ' As Avg'
set #query = #query + ' From '
set #query = #query + '(select Enroll_Number, Student_Name, Course_Id, Semester, Subject_Name, MarksObtained, Exam_Type from Exam_Result ) ps '
set #query = #query + ' pivot(sum(MarksObtained) for Subject_Name in (' + #subjects + ')) as pvt'
set #query = #query + ' inner join Stud_Info S on S.Enroll_Number = pvt.Enroll_Number '
set #query = #query + ' where pvt.Course_Id = ''' + #Course_Id + ''' and pvt.Semester = ''' + #Semester + ''''
set #query = #query + ' group by S.Enroll_Number, pvt.Student_Name, pvt.Course_Id, pvt.Semester, Exam_Type'
print #query
exec sp_executesql #query
end
Exam_Result table:
CREATE TABLE [dbo].[Exam_Result](
[Result_Id] [int] IDENTITY(1,1) NOT NULL,
[Enroll_Number] [varchar](50) NULL,
[Student_Name] [varchar](100) NULL,
[Course_Id] [varchar](50) NULL,
[Semester] [varchar](50) NULL,
[Subject_Id] [varchar](50) NULL,
[Subject_Name] [varchar](50) NULL,
[MarksObtained] [Varchar](10) NULL,
[Exam_Type] [varchar](50) NULL)
Sample data query...
INSERT into Exam_Result VALUES('11147','Mr.Mack28','CIV','1','PS1','ps1','60','Final')
INSERT into Exam_Result VALUES('11147','Mr.Mack28','CIV','3','PS1','ps1','70','Final')
INSERT into Exam_Result VALUES('11147','Mr.Mack28','CIV','3','PS1','ps1','80','Final')
INSERT into Exam_Result VALUES('11147','Mr.Mack28','CIV','3','PS1','ps1','20','Internal')
INSERT into Exam_Result VALUES('11147','Mr.Mack28','CIV','3','PS1','ps1','22','Internal')
Student_Info table: I just use for retrieved Student_Information like Enroll_Number...
CREATE TABLE [dbo].[Stud_Info](
[Enroll_Number] [varchar](20) NOT NULL,
[Student_Name] [varchar](20) NULL,
[Course_Type] [varchar](20) NULL,
[Course_Id] [varchar](20) NULL,
[Semester] [varchar](20) NULL,
[Password] [varchar](20) NULL,
[Gender] [varchar](6) NULL,
[City] [varchar](15) NULL,
[Mobile_Number] [varchar](10) NULL)
It gives me error like this...
Msg 8117, Level 16, State 1, Line 1
Operand data type varchar is invalid for sum operator.
Rahul: as per you answer I updated like this but it still gives error......
set #query = #query + ' pivot(sum(cast(MarksObtained as int)) for Subject_Name in (' + #subjects + ')) as pvt'
I think it gives error because I am using the MarksObtained column (as varchar(10))...plz give me a suggestion how I can convert varchar to int so that summation of total MarksObtained can be done.
You can convert like this way:
SUM (CONVERT(int,<your varchar column>))
This will work if your varchar column actually holds numeric value. Otherwise, you can try casting it using cast function like:
sum(cast(varchar_column as int))
EDIT:
Created a sample table with just 2 column (name and marksobtained), both of type varchar(10) and inserted some data to it. So that my select * looks like
name marksobtained
Mr. Anil 30
Mr. sunil 70
Mr. patel 70
Summed the marks like
select SUM(cast(marksobtained as int)) as 'totalmarksobtained' from sampletab
Which returned 170.
What values does #subjects have? Post some sample.
you can use "cast" in your query
example:
select sum(cast(Enter_your_field_name as int)) from Table_name
Hope it works for you.

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