How to compare both date and time in T-SQL - sql

I have an sql query where I want to compare BOTH the date and time because I am simulating both date and time. But it seems to be comparing the date part only. Here's the stored procedure:
Create PROCEDURE GPSTest_GPSEvent_DeleteOneUnit (#dateFrom DateTime, #dateTo DateTime, #gpsunit int)
AS
BEGIN
Delete from GPSEvent where GPSUnitID = #gpsunit and GPSEventDateTime between #dateFrom and #dateTo
return ##ROWCOUNT;
END
GO
I don't know if anyone has any idea why it's comparing the date part only?

Related

Procedure time executing counter

I have got a procedure which inserts data from one table to other and one time it takes from example 5 minutes and next time for example 15 minutes.
I want to write code that create a log in my log table when procedure will take more then 10 minutes. Is exists any function or time counter in ms sql that I can use?
Add the following lines into your SP and it should work:
ALTER PROCEDURE YourSP
AS
BEGIN
DECLARE #StartTime AS DATETIME = GETDATE();
... <Your current lines>
IF DATEDIFF(mi, #StartTime, GETDATE()) > 10
INSERT INTO LogTable <YourFields>, MinutesSpent
VALUES <YourValues>, DATEDIFF(mi, #StartTime, GETDATE())
END
Why would you only log particular calls to the stored procedure? You should log all calls and filter out the ones that you want. This week you might be interesting in timings longer than 10 minutes. Next week, the data might grow and it might be 12 minutes.
Or you might change the code to make it more efficient, and it should finish in 2 minutes.
If you are only interested in timing, I would write a rather generic log table, something like this:
create table spTimeLog (
procedureName varchar(255),
startDateTime datetime
endDateTime datetime,
createdAt datetime default getdate()
);
create procedure usp_proc . . .
begin
declare #StartTime datetime = getdate();
. . .
insert into spTimeLog (procedureName, startDateTime, endDateTime)
values ('usp_proc', StartTime, getdate());
end;
Then you can get the information you want when you query the table:
select count(*)
from spTimeLog tl
where tl.procedureName = 'usp_proc' and
endDateTime > dateadd(minute, 10, startDateTime);
In general, when I write stored procedures for a real application, the stored procedures generate audit logs when they enter and exit -- both successfully and when they fail.
You can try this way
declare #start datetime = getdate()
-- your SQL statements
exec dbo.MyStoredProcedure
declare #executionTimeInMilliseconds int = datediff(ms, #start, getdate())

How to pass parameter as date by subtracting days to a SQL stored procedure?

I have a stored procedure which takes two parameters, #FromDate and #ToDate. But the #fromDate should be GetDate()-90. How can I pass the parameter value?
ALTER PROCEDURE spMyProcedure
#FromDate DATE,
#ToDate DATE
AS
BEGIN
// SQL statements
END
I want to execute it like this:
EXEC spMyProcedure #FromDate = GETDATE() - 60, #ToDate = GETDATE()
But it throws an error.
You can not do an alter/math/etc on a value passing to a stored procedure. You can declare a date above the stored procedure and then pass that value like this:
DECLARE #PassDate AS DATETIME
SET #PassDate = GETDATE() - 60
EXEC spMyProcedure #FromDate = #PassDate, #ToDate = GETDATE()
I suspect you are working with SQL Server if so, then use dateadd() function inside the stored procedure
set #FromDate = dateadd(day, -90, getdate())

"Must declare the scalar variable" error when executing a stored procedure

I have tried to make a procedure to insert a price:
create procedure prInsertPrice
#NuggetID varchar(5),
#Unit_Price money,
#Start_Date datetime,
#End_Date datetime
as
begin
DECLARE #date AS DATETIME
SET #date = GETDATE()
if
(
(#NuggetID like 'N[0-9][0-9]')
and
(#Unit_Price is not null)
and
(#Start_Date is not null)
)
begin
print 'Insert Success'
insert NuggetPrice (NuggetId, Unit_Price, Start_Date, End_Date)
values (#NuggetID, #Unit_Price, #Start_Date, #End_Date)
end
else
begin
print 'Failed to insert'
end
end
When I execute the procedure it's fine, but when I run the procedure like this:
EXEC prInsertPrice 'N01', 20000, #date, null
I get the error message:
Must declare the scalar variable #date.
Why is this and how can I correct the problem?
The #date in the exec statement is different then the one in the stored proc.
You should do something like:
DECLARE #date AS DATETIME
SET #date = GETDATE()
EXEC prInsertPrice 'N01', 20000, #date, null
When you run:
EXEC prInsertPrice 'N01', 20000, #date, null
You are passing the variable #date as the third parameter to your stored procedure, as #Start_Date. This is entirely separate from the #date variable which you have declared inside the stored procedure itself, which gets declared and initialised after the procedure has been called, as it executes.
If you have not initialised the #date variable which is being passed as a parameter to the stored procedure before calling the stored procedure, then you will get the error you have described.
So, you need to declare and initialise this variable first:
DECLARE #date DATETIME = '2017-01-01' -- You can whatever date value you require here
EXEC prInsertPrice 'N01', 20000, #date, null
This should prevent the error.
Note: You can also separate the declaration and initialisation of the #date variable if you would prefer:
DECLARE #date DATETIME
SET #date = '2017-01-01'
In addressing your underlying problem though or preventing bad data being inserted into your NuggetPrice table though, I would agree with Prdp's suggestion of adding a CHECK Constraint to the table, for example:
ALTER TABLE NuggetPrice
ADD CONSTRAINT CK_NuggetPrice CHECK (NuggetID LIKE 'N[0-9][0-9]'
AND Unit_Price IS NOT NULL
AND Start_Date IS NOT NULL)
This would also prevent anyone from inserting records which do not agree with the logic specified.
Already other two answers gave enough information on the reason for error so am not going to talk about it. Here is different approach to solve the data validation
Instead of creating a Stored Procedure to restrict inserting bad data into table, I would suggest you to create a Check constraint to do this
ALTER TABLE NuggetPrice
ADD CONSTRAINT CK_NuggetPrice CHECK (NuggetID LIKE 'N[0-9][0-9]' AND Unit_Price IS NOT NULL AND Start_Date IS NOT NULL)
This will make sure nobody inserts bad data in NuggetPrice

SQL Server 2012 stored procedure runs slow

I have a SQL Server stored procedure and it runs fine on SQL Server 2008 R2.
When I try to run it on SQL Server 2012, it takes very very long time to run.
But if I create local variables inside the stored procedure and copy the values of input parameters into those local variables and use them instead of input parameters, query runs and returns result faster than on SQL Server 2008 R2 database (please note both 2008 R2 and 2012 servers run on the same box).
Could you please shed some light on what is going on here?
By creating local variables and rebinding values you disable parameter sniffing:
Parameter sniffing is the process whereby SQL Server creates an
optimal plan for a stored procedure by using the calling parameters
that are passed the first time a stored procedure is executed
Every subsequent call to the same store procedure with the same parameters will also get an optimal plan, whereas calls with different parameter values may not always get an optimal plan
Run slows:
CREATE PROC [dbo].[DisplayBillingInfo]
#BeginDate DATETIME,
#EndDate DATETIME
AS
BEGIN
SELECT BillingDate, BillingAmt
FROM BillingInfo
WHERE BillingDate between #StartDate AND #StopDate;
END
Run fast (because it has to calculate new execution plan each time):
CREATE PROC [dbo].[DisplayBillingInfo]
#BeginDate DATETIME,
#EndDate DATETIME
AS
BEGIN
DECLARE #StartDate DATETIME = #BeginDate;
DECLARE #StopDate DATETIME = #EndDate;
SELECT BillingDate, BillingAmt
FROM BillingInfo
WHERE BillingDate between #StartDate AND #StopDate;
END
The case is SQL Server optimizer cannot reuse cached plan and evaluate it each time.
This is the same as you use WITH RECOMPILE:
CREATE PROC [dbo].[DisplayBillingInfo]
#BeginDate DATETIME,
#EndDate DATETIME
WITH RECOMPILE
AS
BEGIN
SELECT BillingDate, BillingAmt
FROM BillingInfo
WHERE BillingDate between #StartDate AND #StopDate;
END
using query hint:
CREATE PROC [dbo].[DisplayBillingInfo]
#BeginDate DATETIME,
#EndDate DATETIME
AS
BEGIN
SELECT BillingDate, BillingAmt
FROM BillingInfo
WHERE BillingDate between #StartDate AND #StopDate
OPTION(RECOMPILE);
-- OPTION (OPTIMIZE FOR (#StartDate UNKNOWN, #StopDate UNKNOWN))
END

Running 1 procedure twice using a single procedure

I have a stored procedure that is run from a SSRS report, my problem now is that I need to include data from the previous year in the report. I wanted to be able to run the report once with the set of parameters an than a second time with the previous years data to include into my report to be able to compare the data line by line. What I have is creating an error. I am somewhat new at SQL Server, any help is much appreciated. This is built in SQL Server 2008
DECLARE
#StartDate datetime,
#EndDate datetime,
#iClientID int,
#iServiceLevelID int
SET #StartDate = '1-1-13'
SET #EndDate = '12-30-13'
SET #iClientID = null
SET DATEFIRST 7
DECLARE #DATA table(iclientID int,
sClientCode varchar(8),
sClientName varchar(50),
sServiceLevelName varchar(50),
DeailyProductionAverage float,
CorrectionPercentage float,
AverageAging float,
decProduction float,
EffectedDate datetetime,
RepID int,
FirstName varchar(50),
LastName varchar(50),
Completed float)
insert into #DATA
exec procSSRS_ClientPerformanceNew_2 #StartDate,
#EndDate,
#iClientID,
#iServiceLevelID
insert into #DATA
exec procSSRS_ClientPerformanceNew_2 dateadd(year, -1, #StartDate)
dateadd(year, -1, #Enddate)
#iClientID
#iServiceLevelID
You are missing the commas in your parameter list when you call the procedure second time. Change your code to this to make it work:
exec procSSRS_ClientPerformanceNew_2
dateadd(year,-1,#StartDate),
dateadd(year,-1,#Enddate),
#iClientID,
#iServiceLevelID
In SQL Server, when passing an argument to a stored procedure, the argument can be either a constant or a variable. It cannot be e.g. a mathematical expression, nor can it be a function call.
So, in order to call the procedure again with the different data range, you will need to store the results of dateadd calls to variables and use those as arguments. For instance, you could re-use #StartDate and #EndDate for that if their original values are not needed later:
...
set #StartDate = dateadd(year,-1,#StartDate);
set #EndDate = dateadd(year,-1,#Enddate);
insert into #DATA
exec procSSRS_ClientPerformanceNew_2 #StartDate,
#EndDate,
#iClientID,
#iServiceLevelID
;
or you could declare two more datetime variables.