SQL Server Stored Procedure parameters affect speed of query - Why? - sql-server

I am running a stored procedure on SQL Server 2005 and calling it from a VB.net application.
This stored procedure was taking over 3 minutes to run and I started working on way to speed it up. Quite by accident I stumbled on a solution that reduced the run time from 3 minutes to 3 seconds (no joke, I'm dead serious).
But I don't understand why.
The only 2 parameters that I pass are a start date and an end date (used in the WHERE clause) as so:
ALTER PROCEDURE get_OrderLinessByRegion
#DateFrom DATETIME,
#DateTo DATETIME
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
blah, blah, blah
Though some testing I found that when I hard coded the dates in the stored procedure the run times were cut from 3 minutes to 3 seconds.
I ended up with this:
ALTER PROCEDURE get_OrderLinessByRegion
#DateFrom DATETIME,
#DateTo DATETIME
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE #StartDate AS DATETIME
DECLARE #EndDate AS DATETIME
SET #StartDate = #DateFrom
SET #EndDate = #DateTo
blah, blah, blah
Can anyone tell me why the second version runs so much faster ?
Thanks so much !!

This sounds like a case of bad parameter sniffing. You can read this article for a detailed explanation. http://sqlinthewild.co.za/index.php/2007/11/27/parameter-sniffing/

Related

C++ fieldtype Datetime2 instead of Datetime

We updated our SQL Server database from 2012 to 2016 recently.
Now, our very old C++ programs run into an issue. Very old means, there is no one left who can maintain the code anymore.
The problem is: In the code itself, the Date Fields are initialized as
RFX_Date(pFX, _T("[CREATION_DATE_CENTRAL]"), m_CREATION_DATE_CENTRAL);
The query, which is executed onto the database looks like this:
EXECUTE sp_executesql
N'SELECT * FROM ADDON_Table
WHERE NR = #number
and CREATION_DATE_LOCAL = #date1
and CREATION_DATE_CENTRAL = #date2',
N'#number int, #date1 datetime2, #date2 datetime2',
9817434, '2019-11-19 10:03:22.000', '2019-11-24 19:24:38.5270000';
At least one row should be returned. But the query returns no row.
I figured out, that after changing the datatype of date2 from datetime2 to datetime returns a row.
EXECUTE sp_executesql
N'SELECT * FROM ADDON_Table
WHERE NR = #number
and CREATION_DATE_LOCAL = #date1
and CREATION_DATE_CENTRAL = #date2',
N'#number int, #date1 datetime2, #date2 datetime',
9817434, '2019-11-19 10:03:22.000', '2019-11-24 19:24:38.527';
My conclusion is, that somethings happened after updating the DB to 2016 with the datetime/datetime2 implementation.
Don't know if our Application/ODBC uses from now on datetime2 instead of datetime. Or is there a new behavior of the sp_executesql.
It would be great if someone can help me.

Error converting data type varchar to datetime. Need to return records based on the date or all records if no date is specified

I have implemented a storedprocedure and basically want the storedprocedure to return all records if no parameter is sent or records based on parameter sent. I am using date as the parameter. I am getting an error when executing exec [dbo].[getLog] '27/07/2017' . The error is
Error converting data type varchar to datetime.
Could somebody tell me what is incorrect in the logic
Create PROCEDURE [dbo].[getLog]
#dateFrom datetime
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
SELECT * from [CoreAnalytics].[dbo].[Logs]
where [TimeStamp] > ISNULL(#dateFrom, 0) ;
END
GO
If I understand you correct you want to return all records if #dateFrom is null, or filter on that variable.
I think you need something like this then
Create PROCEDURE [dbo].[getLog] #dateFrom datetime
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
SELECT * from [CoreAnalytics].[dbo].[Logs]
where (#dateFrom is null or [TimeStamp] > #dateFrom)
END
Make sure you are passing a valid datetime when calling the procedure.
It is best to use an universal format that will work with any database,
yyyyMMdd is a format that will always work.
http://karaszi.com/the-ultimate-guide-to-the-datetime-datatypes
exec [dbo].[getLog] '20170727'
should always work

SQL Server stored procedure coming up empty

I have a SQL Server stored procedure that is not returning any data when I plug in my parameter...
ALTER PROCEDURE dbo.EncumBugSearch
#year datetime
AS
BEGIN
SET NOCOUNT ON;
select *
From dbo.BudgetEncumberedTbl as bet
where year(dateadd(month,-3,bet.be_dateposted)) = #year
order by be_dateposted desc
END
GO
This returns nothing, however, when I plug in a number for the parameter (i.e. 2011) then I get the correct results... any ideas?
Your parameter is a datetime, when it should be an int.

What is wrong with this simple SQL? Fails when put in a stored procedure works otherwise

When I ran as is, it works perfectly fine but putting this exact code into a stored procedure in SQL 2005 fails.
I get this error
Msg 102, Level 15, State 1, Procedure GetCurrentLoadDate, Line 23.
Incorrect syntax near '#vardate'.
What is wrong with this call that it can work as a declaration and return the result set but fail if put in stored procedures?
declare #date datetime
declare #vardate varchar(10)
set #date = getDate()
set #vardate = CONVERT(varchar(10), #date ,101)
select tableloaded, insertdatetime, sourcesystemdatetime, FriendlyDescription
from dbo.tbl_loadSourcedates_dttm
where CONVERT(varchar(10), insertdatetime, 101) = #vardate
Thanks
Dhiren
You are probably missing the END at the end of the stored proc definition that you neglected to show us. I get the same error If I append
create proc foo
as
begin
to the beginning of your posted code.
Do you have exactly this?
CREATE PROCEDURE GetCurrentLoadDate
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 #date datetime
declare #vardate varchar(10)
set #date=getDate()
set #vardate=CONVERT(varchar(10), #date ,101)
select tableloaded,insertdatetime,sourcesystemdatetime,FriendlyDescription
from dbo.tbl_loadSourcedates_dttm
where CONVERT(varchar(10), insertdatetime ,101)=#vardate
END
GO
Because it looks to me that you are missing something when you declare your proc since you are getting a syntax exception on the very first line.

SQL Server 2008 Stored Procedure

I cannot store the date data type variables using stored procedure. My code is:
ALTER PROCEDURE [dbo].[Access1Register]
-- Add the parameters for the stored procedure here
#MobileNumber int,
#CitizenName varchar(50),
#Dob char(8),
#VerificationCode int
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
select CAST(#dob As DATE)
Insert Into Access1 (MobileNo,CitizenName,Dob,VerificationCode)
values(#MobileNumber,#CitizenName,#Dob,#VerificationCode)
go
If I exec this procedure it is executing, but there is an error occured in the date type variable. It's raising the error as invalid item '-'.
It depends on how you pass in the #Dob values.
Your best bet is to use the ISO8601 format - 'YYYYMMDD' - since that will always convert to DATE properly - regardless of your language and regional settings on your SQL Server machine.
It depends on the date format that you pass.
If it is 'mm-dd-yy' you can use CONVERT(DATE, #Dob, 110), if it is 'dd-mm-yy' then CONVERT(DATE, #Dob, 105).
In which format you are passing the #Dob values? And what error you are getting exactly?
If you will pass the #Dob values in the format of mm-dd-yy, it should work correctly and no errors will be there.

Resources