This is my stored procedure that I want to change into a table-valued function. I don't know how to create a table-valued function, please help me
ALTER procedure [dbo].[GENRATE_BATCHNO]
#StrBatchNo varchar(200) output,
#BatchNum bigint output,
#RetType bigint output,
#Fid int,
#WcID int,
#PrCompID bigint,
#BsProductID bigint,
#CreationDt datetime
as
begin
Declare #RestartFrom int, #BatchID bigint,#BatchMaxVal bigint,#ParaType int, #BatchValue varchar(50),#BatchFormat varchar(10),
#Digits bigint,#BsParaID int,#StrBatchVal varchar(200),#StrVal varchar(200), #Type bigint, #Base int,#CompanyId int, #EffDate Date
if exists (select 'x' from Tblbatchnosetting where baseprid=#BsProductID and PrCompID=#PrCompID and wcid=#WcID and effdate <= #CreationDt )
Declare Cur_SttgMaster Cursor For Select RestartFrom,BatchID, Isnull(type,1),Base, CompanyId as Type,EffDate from Tblbatchnosetting where baseprid=#BsProductID and PrCompID=#PrCompID and wcid=#WcID
and effdate <= #CreationDt order by effdate desc
else
begin
Declare Cur_SttgMaster Cursor For Select RestartFrom,BatchID, Isnull(Type,1) as Type,Base,CompanyId,EffDate from Tblbatchnosetting where Companyid in (Select MfgID from TblBaseProduct where BsProductID=#BsProductID) and Base=1 and PrCompID=#PrCompID and wcid=#WcID
and effdate <= #CreationDt order by effdate desc
end
open Cur_SttgMaster
Fetch Next From Cur_SttgMaster Into #RestartFrom, #BatchID, #Type, #Base, #CompanyId,#EffDate
Close Cur_SttgMaster
Deallocate Cur_SttgMaster
Set #RetType = #Type
If #RestartFrom <> 0
begin
if #Base=1
begin
if #RestartFrom=1 --- Month ReStart
Select #BatchMaxVal = isnull(Max(BatchNum),0) from tblbatchmaster where PrCompID=#PrCompID and BasePrid in (Select Bsproductid from TblBaseProduct where Mfgid=#CompanyId) and Wcid=#Wcid
and fid=#Fid and month(CreatDate)=Month(#CreationDt)
else if #RestartFrom=2 --- Yearly ReStart
Select #BatchMaxVal = isnull(Max(BatchNum),0) from tblbatchmaster where PrCompID=#PrCompID and BasePrid in (Select Bsproductid from TblBaseProduct where Mfgid=#CompanyId) and Wcid=#Wcid
and Year(CreatDate)=Year(#CreationDt) and CREATDATE >=#EffDate
else if #RestartFrom=3 --- never ReStart
Select #BatchMaxVal = isnull(Max(BatchNum),0) from tblbatchmaster where PrCompID=#PrCompID and BasePrid in (Select Bsproductid from TblBaseProduct where Mfgid=#CompanyId) and Wcid=#Wcid
end
else if #Base=2
BEGIN
if #RestartFrom=1 --- Month ReStart
Select #BatchMaxVal = isnull(Max(BatchNum),0) from tblbatchmaster where PrCompID=#PrCompID and BasePrid=#BsProductID and Wcid=#Wcid
and fid=#Fid and month(CreatDate)=Month(#CreationDt)
else if #RestartFrom=2 --- Yearly ReStart
Select #BatchMaxVal = isnull(Max(BatchNum),0) from tblbatchmaster where PrCompID=#PrCompID and BasePrid=#BsProductID and Wcid=#Wcid
and Year(CreatDate)=Year(#CreationDt) and CREATDATE >=#EffDate
else if #RestartFrom=3 --- Never ReStart
Select #BatchMaxVal = isnull(Max(BatchNum),0) from tblbatchmaster where PrCompID=#PrCompID and BasePrid=#BsProductID and Wcid=#Wcid
END
Declare Cur_SttgDetail Cursor For Select BsParaID,ParaType,BatchValue,BatchFormat,Digits from TblBatchNoSettingDetail where BatchID=#BatchID order by SeqNo
Open Cur_SttgDetail
Fetch Next From Cur_SttgDetail Into #BsParaID,#ParaType,#BatchValue,#BatchFormat,#Digits
Set #StrVal=''
While ##Fetch_Status=0
begin
Set #StrBatchVal=''
if #BsParaID=6 -- for Year
begin
if upper(ltrim(rtrim(#BatchFormat)))='Y'
Set #StrBatchVal=Cast(Cast(right(year(#CreationDt),1)as int) as varchar(2))
else if upper(ltrim(rtrim(#Batchformat)))='YY'
Set #StrBatchVal=Cast(right(year(#CreationDt),2) as varchar(2))
else if upper(ltrim(rtrim(#Batchformat)))='YYYY'
Set #StrBatchVal=Cast(year(#CreationDt) as varchar(4))
end
else if #BsParaID=7 -- For Month
begin
if upper(ltrim(rtrim(#BatchFormat)))='MM'
if Cast(month(#CreationDt) as int) < 10
Set #StrBatchVal= '0' + Cast(month(#CreationDt)as varchar(2))
else
Set #StrBatchVal= Cast(month(#CreationDt)as varchar(2))
else if Upper(ltrim(rtrim(#BatchFormat)))='A'
Set #StrBatchVal=(Select Case cast(Month(#CreationDt)as int)
when 1 then 'A'
when 2 then 'B'
when 3 then 'C'
when 4 then 'D'
when 5 then 'E'
when 6 then 'F'
when 7 then 'G'
when 8 then 'H'
when 9 then 'I'
when 10 then'J'
when 11 then'K'
when 12 then'L'
end)
end
else if #BsParaID=8
begin
if #BatchMaxVal=0
begin
if #RestartFrom=3
begin
if #Batchvalue>=100
begin
Set #StrBatchVal = #BatchValue
Set #BatchNum=Cast(#BatchValue as bigint)
end
else
begin
Set #StrBatchVal = Cast(replicate('0',#Digits-len(#BatchValue)) as varchar(10)) + #BatchValue
Set #BatchNum=Cast(#BatchValue as bigint)
end
end
else
begin
Set #StrBatchVal = Cast(replicate('0',#Digits-len(#BatchValue)) as varchar(10)) + #BatchValue
Set #BatchNum=Cast(#BatchValue as bigint)
end
end
else
begin
Set #BatchMaxVal=#BatchMaxVal+1
Set #StrBatchVal = cast(replicate('0',#Digits-len(cast(#BatchMaxVal as varchar(10)))) as varchar(10)) + Cast(#BatchMaxVal as varchar(10))
Set #BatchNum=#BatchMaxVal
end
end
if #StrBatchVal=''
Set #StrBatchVal=#BatchValue
Set #StrVal = #StrVal + #StrBatchVal
Fetch Next From Cur_SttgDetail Into #BsParaID,#ParaType,#BatchValue,#BatchFormat,#Digits
end
Close Cur_SttgDetail
Deallocate Cur_SttgDetail
Set #StrBatchNo = cast(#StrVal as varchar(200))
end
Return #RetType
Return #BatchNum
Return #StrBatchNo
end
Can you tell me how to call this stored procedure I try but fail
string strsql = "Exec [dbo].[GENRATE_BATCHNO] " + Fid + "," + WcID + "," + PrCompID + "," + BsProductID + ",'" + CreationDate + "' ";
Reader = dc.GetReader(strsql);
There are two ways
rewrite your sp as a table value function (http://msdn.microsoft.com/en-us/library/ms187650.aspx)
using an ugly way of OpenQuery see below example
CREATE FUNCTION dbo.myfunction
(#f1 char(14), #d1 smalldatetime, #tip char(1))
RETURNS TABLE
AS
RETURN
(SELECT * FROM openquery('SERVER', 'exec dbo.sp #f1, #d1, #tip'))
Related
i have a temp table having record id, module id and status id, now i have to check every row of that temp table and according to #levelid i have to update corresponding table with that status id,
but below code never goes to else if condition, i am new to mssql seeking for your valuable answers :)
DECLARE #MyCursor CURSOR;
DECLARE #LevleId INT,
#STATUS VARCHAR(max),
#RECID VARCHAR(max);
BEGIN
SET #MyCursor = CURSOR
FOR SELECT TOP 1000 level_id,
status_id,
record_id
FROM #temp_record_id_typ2
WHERE approval_typ_id = 2
OPEN #MyCursor
FETCH next FROM #MyCursor INTO #LevleId, #STATUS, #RECID
WHILE ##FETCH_STATUS = 0
BEGIN
IF ( #LevleId = 1
AND #STATUS != 3 )
BEGIN
SELECT #Update_Typ2_Rec = N'UPDATE hrms_approvals SET approval_status_id = ' +
#STATUS
+ ' WHERE record_id = ' + #RECID
+ ' AND module_id = ' + #Module_id +
' ';
--SELECT #Update_Typ2_Rec
EXECUTE Sp_executesql
#Update_Typ2_Rec;
SELECT #UPDATE_MODULE_TABLE = N'UPDATE ' + #TableName +
' SET approval_status_id = 9 WHERE id = '
+ #RECID + '';
--SELECT #UPDATE_MODULE_TABLE
EXECUTE Sp_executesql
#UPDATE_MODULE_TABLE;
PRINT 'LevleId = 1'
END
ELSE IF ( #LevleId = 2
AND #STATUS != 3 )
BEGIN
SELECT #Update_Typ2_Rec =
N'UPDATE hrms_approvals SET approval_status_id = '
+ #STATUS + ' WHERE record_id = '
+ #RECID + ' AND module_id = '
+ #Module_id + ' ';
--SELECT #Update_Typ2_Rec
EXECUTE Sp_executesql
#Update_Typ2_Rec;
SELECT
#UPDATE_MODULE_TABLE = N'UPDATE ' + #TableName
+ ' SET approval_status_id = 10 WHERE id = ' + #RECID + '';
--SELECT #UPDATE_MODULE_TABLE
EXECUTE Sp_executesql
#UPDATE_MODULE_TABLE;
PRINT 'LevleId = 2'
END
ELSE IF ( #LevleId = 3
AND #STATUS != 3 )
BEGIN
SELECT #STATUS,
#LevleId
PRINT 'LevleId = 3'
END
ELSE IF ( #LevleId = 4
AND #STATUS != 3 )
BEGIN
SELECT #STATUS,
#LevleId
PRINT 'LevleId = 4'
END
ELSE IF ( #LevleId = 5
AND #STATUS != 3 )
BEGIN
SELECT #STATUS,
#LevleId
PRINT 'LevleId = 5'
END
FETCH next FROM #MyCursor INTO #LevleId, #STATUS, #RECID
END;
CLOSE #MyCursor;
DEALLOCATE #MyCursor;
END;
Try this below code,You didn't declare this Parameters "#TableName and #ModuleId", Check your code and assign the value for #TableName and #ModuleId
Declare #Counter int=1
,#Tot_Count int=0
,#LevleId int
,#Status int
,#RecId int
,#Module_id int
,#TableName varchar(30)=''
Create Table #Temp_Table
(
Id int identity(1,1)
,level_id int
,status_id int
,record_id int
,Module_id int
)
Insert into #Temp_Table
(
level_id,status_id,record_id
)
Select level_id
,status_id
,record_id
,Module_id
from #temp_record_id_typ2
where approval_typ_id = 2
Select #Tot_Count=Count(1) from #Temp_Table
While #Tot_Count >= #Counter
Begin
Select #LevleId=level_id
,#Status=status_id
,#RecId=record_id
,#Module_id=Module_id
from #Temp_Table
where Id=#Counter
IF ( #LevleId = 1 AND #STATUS <> 3 )
BEGIN
Exec
('
UPDATE hrms_approvals
SET approval_status_id = ' + #STATUS + '
WHERE record_id = ' + #RECID + '
AND module_id = ' + #Module_id +'
UPDATE '+ #TableName +'
SET approval_status_id = 9
WHERE id = '+ #RECID + '
')
PRINT 'LevleId = 1'
END
ELSE IF ( #LevleId = 3 AND #STATUS <> 3 )
BEGIN
SELECT #STATUS,
#LevleId
PRINT 'LevleId = 3'
END
ELSE IF ( #LevleId = 4 AND #STATUS <> 3 )
BEGIN
SELECT #STATUS,
#LevleId
PRINT 'LevleId = 4'
END
ELSE IF ( #LevleId = 5 AND #STATUS <> 3 )
BEGIN
SELECT #STATUS,
#LevleId
PRINT 'LevleId = 5'
END
Set #Counter+=1
End
Drop table #Temp_Table
Below is the code snippet in which MIN function using. When execute below code it is giving an error.
CREATE FUNCTION [dbo].[FN_TempCalcTransportExemp]
(
#EmployeeID varchar(20),
#PayElement varchar(20),
#Month varchar(10),
#FinYear varchar(10)
)
RETURNS decimal
AS
BEGIN
DECLARE #TarnsportExemption decimal(18,2) = 0
DECLARE #TDSIsFullExemption bit
DECLARE #PermanentPhysicalDisability decimal(18,2) = 0
DECLARE #UsingComapnyCar bit
DECLARE #Conveyance decimal(18,2) = 0
DECLARE #TransYes decimal(18,2) = 0
DECLARE #TransNo decimal(18,2) = 0
DECLARE #MinConveyance decimal(18,2) = 0
DECLARE #MinTransport decimal(18,2) = 0
SELECT
#TDSIsFullExemption = TDSDetailsFullExemption,
#TransYes = TDSDetailsYes,
#TransNo = TDSDetailsNo
FROM
tbl_TDSSettingDetails
WHERE
TDSSettingsDetailID = 2
SELECT
#Conveyance = #Month
FROM
tbl_Income
WHERE
EmployeeID = #EmployeeID
AND Element = #PayElement
AND FinancialYear = #FinYear
SELECT
#UsingComapnyCar = UsingCompanyCar,
#PermanentPhysicalDisability = PermanentPhysicalDisability
FROM
tbl_Employee_TDS
WHERE
EmployeeID = #EmployeeID
AND TDSFinancialYear = #FinYear
IF (#TDSIsFullExemption = 1)
BEGIN
SET #TarnsportExemption = #Conveyance
END
ELSE
BEGIN
IF (#UsingComapnyCar = 1)
BEGIN
IF (#Conveyance = 0)
BEGIN
SET #MinConveyance = 0
END
ELSE
BEGIN
SET #MinConveyance = #Conveyance
END
IF (#PermanentPhysicalDisability = 1)
BEGIN
SET #MinTransport = #TransYes
END
ELSE
BEGIN
SET #MinTransport = #TransNo
END
SET #TarnsportExemption = MIN(#MinConveyance, #MinTransport)
END
ELSE
BEGIN
SET #TarnsportExemption = 0
END
END
RETURN #TarnsportExemption
END
Error Message:
Msg 174, Level 15, State 1, Procedure FN_TempCalcTransportExemp, Line
66
The MIN function requires 1 argument(s).
set #TarnsportExemption = MIN(#MinConveyance,#MinTransport) - The MIN function is not what you think it is.
You probably want to do something like this:
set #TarnsportExemption = CASE WHEN #MinConveyance < #MinTransport THEN
#MinConveyance
ELSE
#MinTransport
END
Another option is this:
SELECT #TarnsportExemption = MIN(val)
FROM
(
SELECT #MinConveyance as val
UNION ALL
SELECT #MinTransport as val
)
And one more option is to use the values clause:
SELECT #TarnsportExemption = MIN(val)
FROM (VALUES ( #MinConveyance), (#MinTransport)) AS value(val)
Change your min statement like below MIN. Please refer MIN (Transact-SQL)
--fROM
set #TarnsportExemption = MIN(#MinConveyance,#MinTransport)
--To
SELECT #TarnsportExemption = MIN(A) FROM (
SELECT #MinConveyance A
UNION ALL
SELECT #MinTransport
)AS AA
In SQL, MIN function will return you minimum value of a column from selected list; so you can use MIN only in inline queries.
e.g. Select min(Salary) from Tbl_Employee
So, in your case either you can use case when then or union all to get minimum value from two variables as:-
SET #TarnsportExemption = CASE WHEN #MinConveyance < #MinTransport THEN #MinConveyance ELSE #MinTransport END
OR
SELECT #TarnsportExemption = MIN(TEMPS.[VALUE])
FROM (
SELECT #MinConveyance AS VALUE
UNION ALL
SELECT #MinTransport AS VALUE
) AS TEMPS
I want to replace all e_Mail column where in #tablename with my users table (my main table).
For example:
#tablename
[name] [eMail] // columns
------------------------------------------------------
name surname blahblah#gmail.com
My users table
[name] [eMail]
----------------------------------------
name surname blahblah#hotmail.com
I want to update this row's eMail column as 'blahblah#hotmail.com' in #tablename.
What will procedure do?
1- Get first value of eMail column from #tablename
2- Split value (split char: #) and get first value (for example, if value blahblah#gmail.com, get gmail.com)
3- Search first value in users table
4- When the find value in users table, (Code must find blahblah#hotmail.com) Update eMail as blahblah#hotmail.com in #tablename
5- Get second value of eMail column from #tablename
.
.
.
So, I write a stored procedure. But this procedure is not working. Where is the problem?
Create Proc update_eMail
(#tablename nvarchar(50),
#columnname nvarchar(50))
AS
Begin
Declare #get_oldeMail nvarchar(100)
Declare #get_eMail nvarchar(100)
Declare #get_SplitValue nvarchar(100)
Declare #get_oldSplitValue nvarchar(100)
Declare #rowNumber int
Declare #users_rowNumber int
Declare #i int
Declare #j int
Declare #q_getRowNumber NVARCHAR(MAX)
Declare #q_getoldeMail NVARCHAR(MAX)
Declare #q_UpdateQuery NVARCHAR(MAX)
SET #q_getRowNumber = N'SELECT Count(ID)
FROM ' + QUOTENAME(#tablename)
EXECUTE #rowNumber = sp_executesql #q_getRowNumber
/*Set #rowNumber = (Select Count(ID) from #tablename)*/
Set #users_rowNumber = (Select Count(ID) from tblusers)
Set #i = 1
Set #j = 1
While(#i <= #rowNumber)
BEGIN
Set #q_getoldeMail = '(SELECT Lower(#columnname) FROM (
SELECT
ROW_NUMBER() OVER (ORDER BY ID) AS rownumber
,ID
,[Name]
,[Description]
,[Status]
,[AssignedTo]
,[AssignedToMail]
,[CC]
FROM' + #tablename + '
) AS ar
WHERE rownumber = #i)'
EXECUTE #get_oldeMail = sp_executesql #q_getoldeMail
Set #get_oldeMail = REPLACE(#get_oldeMail,'ı','i')
WHILE LEN(#get_oldeMail) > 0
BEGIN
IF CHARINDEX('#',#get_oldeMail) > 0
SET #get_oldSplitValue = SUBSTRING(#get_oldeMail,0,CHARINDEX('#',#get_oldeMail))
ELSE
BEGIN
SET #get_oldSplitValue = #get_oldeMail
SET #get_oldeMail = ''
END
SET #get_oldeMail = REPLACE(#get_oldeMail,#get_oldSplitValue + '#' , '')
END
While(#j <= #users_rowNumber)
BEGIN
Set #get_eMail = (SELECT Replace(Lower(eMail),'ı','i') FROM (
SELECT
ROW_NUMBER() OVER (ORDER BY ID) AS rownumber
,eMail
FROM tblusers) AS ar
WHERE rownumber = #j)
WHILE LEN(#get_eMail) > 0
BEGIN
IF CHARINDEX('#',#get_eMail) > 0
SET #get_SplitValue = SUBSTRING(#get_eMail,0,CHARINDEX('#',#get_eMail))
ELSE
BEGIN
SET #get_SplitValue = #get_eMail
SET #get_eMail = ''
END
SET #get_eMail = REPLACE(#get_eMail,#get_SplitValue + '#' , '')
END
if(#get_splitValue = #get_oldSplitValue)
begin
Set #q_UpdateQuery = 'Update ar Set ' + #columnname + ' = ' + #get_email + ' Where rownumber = ' +#i
EXECUTE sp_executesql #q_UpdateQuery
break
end
SET #j = #j+1
END
SET #i = #i+1
END
End
Thanks in advance.
I am very new to SQL Server and finally got my code to run, but its very slow. My database is a bit on the big side (1.22mill rows, 3 columns) and I have some while loops, which I know isn't ideal but I couldn't find a way around it.
Any help would be greatly appreciated!!!
declare #b float
declare #c float
declare #dateloopfora datetime
declare #dateloopforc datetime
BEGIN
SET #MYCURSOR = CURSOR FOR
SELECT DISTINCT [STOCKS] FROM [tsxvPrices].[dbo].[3coldata]
OPEN #MYCURSOR
FETCH NEXT FROM #MYCURSOR INTO #STOCK
set #end = '12/30/2012'
WHILE ##FETCH_STATUS = 0
BEGIN
print ('Stockname restart: ' + #stock)
SET #dateloop = '01/01/2012'
WHILE (#dateloop <= #end)
BEGIN
set #datedelta = 0
SET #dateloop = dateadd(day,1,#dateloop)
set #b = (SELECT [val] FROM [tsxvPrices].[dbo].[3coldata] WHERE( [dates] = #dateloop and [stocks] = #stock))
WHILE (#datedelta < 4)
BEGIN
set #datedelta = #datedelta + 1
if (#b is null)
begin
SET #dateloop = dateadd(day,1,#dateloop)
set #b = (SELECT [val] FROM [tsxvPrices].[dbo].[3coldata] WHERE( [dates] = #dateloop and [stocks] = #STOCK))
/*print ('b= ' + cast( #b as varchar(10)) + ' dateadd1=' + cast( #datedelta as varchar(10))) */
end
END
SET #datedelta = 0
set #a = (SELECT [val] FROM [tsxvPrices].[dbo].[3coldata] WHERE( [dates] = dateadd(day,-1,#dateloop) and [stocks] = #stock))
set #c = (SELECT [val] FROM [tsxvPrices].[dbo].[3coldata] WHERE( [dates] = dateadd(day,+96,#dateloop) and [stocks] = #stock))
if #b/#a < 0.8
begin
WHILE (#datedelta < 4)
BEGIN
set #datedelta = #datedelta + 1
if (#a is null)
begin
SET #dateloopfora = dateadd(day,-#datedelta,#dateloop)
set #a = (SELECT [val] FROM [tsxvPrices].[dbo].[3coldata] WHERE( [dates] = #dateloopfora and [stocks] = #STOCK))
/*print ('b= ' + cast( #b as varchar(10)) + ' dateadd1=' + cast( #datedelta as varchar(10))) */
end
if (#c is null)
begin
SET #dateloopforc = dateadd(day,96+#datedelta,#dateloop)
set #c = (SELECT [val] FROM [tsxvPrices].[dbo].[3coldata] WHERE( [dates] = #dateloopforc and [stocks] = #STOCK))
/*print ('b= ' + cast( #b as varchar(10)) + ' dateadd1=' + cast( #datedelta as varchar(10))) */
end
END
/*print ('Stockname: ' + #stock)
print #dateloop
print('daily')
print #b/#a
print ('quarterly')*/
print #c/#b
/*print ('======================')*/
end
END
FETCH NEXT FROM #MYCURSOR INTO #STOCK
END
CLOSE #MYCURSOR
DEALLOCATE #MYCURSOR
I can see one simple problem straight away, you're using a Cursor.
This is probably one of the worst ways to process SQL, it's very slow and it's forcing the SQL engine to be very inefficient.
You're new to SQL so I'll forgo a technical explanation, but please have a look at this other StackOverflow question:
Why is it considered bad practice to use cursors in SQL Server?
I may be able to offer further advice, What version of SQL are you using?
I'm trying to create a procedure to verify annual dates. The date is stored one time in the BD, but in the calendar on my winform it shows annually(I use annually bolded dates in C#). So what I want to do with the query, is to check is the month and the day are like the date stored in the table, but does not work. This is my query:
SELECT IdCalendar,
Description,
DateCalendar,
Annualy
FROM Calendar
WHERE
(DATEPART(MONTH,DateCalendar) like DATEPART(MONTH,#DateCalendar)) AND
(DATEPART(DAY,DateCalendar) like DATEPART(DAY,#DateCalendar))
And for example, my stored DateCalendar is '2015-12-04', and I my paramenter #DateCalendar is '2016-12-04'. Any idea about how to do a better query?
EDIT
The query does not have any error or warning. Just returns 0 rows. And my DateCalendar is stored as DateTime.
The SP:
CREATE PROC [dbo].[usp_app_Calendar_Search]
#DateCalendar DATETIME,
#Result SMALLINT OUTPUT,
#Message VARCHAR(1000) OUTPUT
AS
BEGIN
DECLARE #vResult SMALLINT, #vMessage VARCHAR(1000)
SELECT #vResult = 0, #vMessage = ''
BEGIN TRY
IF EXISTS (SELECT * FROM Calendar WHERE DateCalendar = #DateCalendar)
BEGIN
IF(#DateCalendar = 0) SET #DateCalendar = NULL
SELECT IdCalendar,
Description,
DateCalendar,
Annualy
FROM Calendar
WHERE
(DATEPART(MONTH,DateCalendar) like DATEPART(MONTH,#DateCalendar)) AND
(DATEPART(DAY,DateCalendar) like DATEPART(DAY,#DateCalendar))
SET #vResult = 1
SET #vMessage = 'Done'
END
ELSE BEGIN
SET #vResult = 0
SET #vMessage = 'Error.'
END
END TRY
BEGIN CATCH
SET #vResult = -1
SET #vMessage = 'Error: ' + ERROR_MESSAGE() + ' Line: ' + CAST(ERROR_LINE() AS VARCHAR)
END CATCH
SELECT #Result = #vResult, #Message = #vMessage
END
Thanks in advance.
The problem is with IF EXISTS (SELECT * FROM Calendar WHERE DateCalendar = #DateCalendar). I rewrite your SP:
CREATE PROC [dbo].[usp_app_Calendar_Search]
#DateCalendar DATETIME,
#Result SMALLINT OUTPUT,
#Message VARCHAR(1000) OUTPUT
AS
BEGIN
DECLARE #vResult SMALLINT = 0
,#vMessage VARCHAR(1000) = '';
IF(#DateCalendar = 0) SET #DateCalendar = NULL;
BEGIN TRY
SELECT IdCalendar,
Description,
DateCalendar,
Annualy
FROM Calendar
WHERE DATEPART(MONTH,DateCalendar) = DATEPART(MONTH,#DateCalendar)
AND DATEPART(DAY,DateCalendar) = DATEPART(DAY,#DateCalendar);
IF ##ROWCOUNT > 0
SELECT #vResult = 1, #vMessage = 'Done'
ELSE
SELECT #vResult = 0, #vMessage = 'Error.';
END TRY
BEGIN CATCH
SET #vResult = -1
SET #vMessage = 'Error: ' + ERROR_MESSAGE() + ' Line: '
+ CAST(ERROR_LINE() AS VARCHAR)
END CATCH
SELECT #Result = #vResult, #Message = #vMessage;
END
EDIT:
Now the WHERE condition is not-SARGable so it means that query optimizer will skip index on DateCalendar column (if exists any).
You can use computed columns like #Tom Page suggested in comment:
ALTER TABLE Calendar ADD MonthCalendar AS DATEPART(MONTH,DateCalendar);
ALTER TABLE Calendar ADD DayCalendar AS DATEPART(day,DateCalendar);
/*Create Index on Calculated Columns for Month and day*/
CREATE INDEX IX_Calendar_Month_Day ON Calendar(MonthCalendar , DayCalendar);
/*Use Computed Column Index in W*/
DECLARE #DateCalendar datetime = '2015-12-25';
SELECT IdCalendar, Description, DateCalendar, Annualy
FROM Calendar
WHERE MonthCalendar = DATEPART(MONTH,#DateCalendar)
AND DayCalendar = DATEPART(DAY,#DateCalenda);