Stored Proc run manually differs from run via job - sql

I have a stored proc which when run manually, produces expected results. When run by the Job Agent, I get very different results and I cannot work out why. The issue relates to the following
declare #date as date
set #date=case datepart(dw,getdate())
when 1 then GETDATE()-3 --Monday so use Friday
when 7 then GETDATE()-2 --Sunday so use Friday
else GETDATE()-1 end
print #date
It appears that when run as a job, #date is being set to GETDATE()-1 regardless on a Monday. But appears to be set to GETDATE()-2 correctly on a Sunday....
What have I cocked up?

Have a look at SET DATEFIRST https://msdn.microsoft.com/en-us/library/ms181598.aspx
One possible reason could be that the job login has a different setting than your own login.

Related

SSRS with a parameter #startdate

I currently have an SSRS report that runs daily with the below SQL code as it should. But, when replication goes down and we miss a day, our Court people would like to be able to manually run a missed date by entering a date #1.
I need some help with setting up the parameter #StartDate, that will run the code below.
I have this SQL:
Select *
from Court
WHERE
case_filed_dt =
CASE WHEN datepart(weekday,getdate())= 2 THEN
datediff(day,3,getdate())
ELSE
datediff(day,1,getdate())
END
Order by court asc
Simple case statement that looks at the date the report is run, if it runs on Monday's, it get Friday's data otherwise previous day's data.
I would like to add a parameter #startdate for my "case_filed_dt" field, to run manually, in case a report is missed.
Example:
If I run for #startdate = '06-06-2022' it will do as my case statement code does, and get data for '06-03-2022'. If I run for #startdate ='06-07-2022', data is for 6-06-2022'.
Thanks,
jer
I would keep this simple.
Change your existing dataset query to accept a parameter (pStartDate) like this..
Select *
from Court
WHERE
case_filed_dt =
CASE WHEN datepart(weekday, #pStartDate)= 2 THEN
datediff(day,3, #pStartDate)
ELSE
datediff(day,1, #pStartDate)
END
Order by court asc
Then in your report, set the parameter's default value to be an expression
=Today()
Then if the report is run as normal with no parameters passed, it will use Today() as the start date or if the report is run manually, any date can be selected by the user.
a few versions on the fiddle, which should get you started, this one using a variable to simulate the effects of the Case statement.
Change the date and see what happens
Declare #DateNow datetime = '2022-06-03'
SELECT #DateNow as YourDate, DATENAME(WEEKDAY, #DateNow) AS DayNow, '',
CASE
WHEN DATENAME(WEEKDAY, #DateNow) = 'Monday' THEN
DateAdd(day,-3,#DateNow)
ELSE
DateAdd(day,-1,#DateNow)
END AS ReportDate
https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=b3ae703d3be9ace930822f7e20230018

I need to create a function that will return number of day in a week on requested date

Something like this (which is not working)
CREATE FUNCTION dbo.udf_DayOfWeek
(#b_date DATETIME)
RETURNS VARCHAR(10)
AS
BEGIN
DECLARE #weekday VARCHAR(10)
IF (SELECT DATENAME(dw, #b_date)
RETURN (#weekday)
END;
GO
after using this
SELECT dbo.udf_DayOfWeek ('May 22, 2016');
GO
to return value of 1-7(number of a day in week)
I am using SQL Server 2014
You are going to want to use DATEPART() versus DATENAME() to get the numeric value, but this can be done inline and really doesn't need it's own function.
SELECT DATEPART(weekday,'May 22, 2016')
And to fix your function syntax...
CREATE FUNCTION dbo.udf_DayOfWeek (#b_date DATETIME)
RETURNS INT
AS
BEGIN
DECLARE #weekday INT
SELECT #weekday = DATEPART(WEEKDAY, #b_date)
RETURN (#weekday)
END
GO
DatePart for weekday uses the DateFirst setting, making it difficult to use consistently. The problem is, some places in the world consider Sunday to be the first day of the week, and other places consider Monday to be the first day of the week. Because of this ambiguity, SQL Server will use the datefirst setting of the login currently connected to the database. To see a list of datefirst settings, run this:
Select * From sys.syslanguages
You can manually set the DateFirst value that persists for the duration of the connection like this:
Set DateFirst 1
SELECT DATEPART(weekday,'May 22, 2016')
Set DateFirst 7
SELECT DATEPART(weekday,'May 22, 2016')
Note that the output of the previous code changes depending on the DateFirst setting.
If you want 1 to always represent Sunday, regardless of the user's language setting, you can use this:
Select DateDiff(Day, 6,#DateVariable) % 7 + 1
Using this information, you can create your user defined function like this:
CREATE FUNCTION dbo.udf_DayOfWeek
(#b_date DATETIME)
RETURNS int
AS
BEGIN
return (
Select DateDiff(Day, 6,#b_date) % 7 + 1
)
END;

SQL Server : get hour from datetime and then change it

I have been trying this for a while and so far research has not gotten me far other than I need to use something called DATEPART (I have no idea how to use this). My SQL Server is not the greatest.
I have declare #DueDate datetime and through a cursor #DueDate will always been the current row's DueDate (datetime) column. This so far works perfectly without issue.
Now what I am trying to do is get the hour out of #DueDate, check to see if it is 0, and if the hour is 0, set the #DueDate hour to midnight and then update the rows DueDate column with this #DueDate variable.
As stated above I have the cursor and variables all working, I just don't know how to get the hour from #DueDate, check what that hour value is, and update the #DueDate variable so its hour is now midnight. I know how the update the table, that is the easy part.
Thanks in advance!
I think this does exactly what you want without using the cursor.
UPDATE [MyTable]
SET DueDate = DATEADD(dd, 1, DueDate) -- add one day (set to midnight)
WHERE DATEPART(hh, DueDate) = 0 -- do this for dates where hour is zero (midnight)
Note that you should avoid using cursors where possible. SQL development requires a different way of thinking. Don't think about iterations, think atomic. You can do most things in a single statement (one statement can be very long if complicated enough).

SQL Start date is current day then end date is 1 month ago even if its not from the first to the last of the month

Ok I am trying to write a query that says get the current date and make it the start date. Then I want to go a month back from that current date for the EndDate. Is it possible to do this? Like if it was 9-15-2010 as the start date can I go a month back from that to 8-15-2010 or is this no possible....what would you do for like 9-20-2010 as the start date since every month has a different amount of days in it? Otherwise if this is not possible how else could I do this? The report will always be run on the 25th of the month so any ideas? I need to go from the 25th back a month....I can get some duplicate records between months if needed but less is obviously better
Right now I am using this:
DECLARE #StartDate DATETIME,
#EndDate DATETIME;
SET #StartDate = DATEADD(m,-1,GETDATE());
SET #EndDate = DATEADD(m, 1, #StartDate);
Does this work?
Also, how would I then say my AuditInsertTimestamp is between #Start adn #EndDate?
Currently I have this:
AND cvn.[AuditInsertTimestamp] BETWEEN #StartDate AND #EndDate ;
This is still giving me dates like 7-26-2010 though....
Thanks!
That should work. Did you try it?
If it doesn't work (and there are only 12 test cases to check if you don't trust the documentation) then you can re-build the date from the date parts.
Here's the problem. It should be like this:
cvn.[Subject] = 'Field Changed (Plate Type)'
AND (
cvn.[Note] LIKE 'Old Type: IRP%New Type: BASE PLATE%'
OR cvn.[Note] LIKE 'Old Type: Base Plate%New Type: IRP%'
)
AND cvn.AuditInsertTimestamp BETWEEN GETDATE() AND DATEADD(MONTH, -1, GETDATE())
AND takes precidence over OR, so you were picking up anything with Old Type:IRP or in the correct date range (with Old Type: Base Plate)
Based on your comment:
Well this is being used to select
records. So if I run it on the 25th I
need 30 days back then my field
AuditInsertTimestamp needs to be
between these 2 dates.
I think you need to do something like this:
SELECT * FROM Table
WHERE AuditInsertTimestamp BETWEEN GETDATE() AND DATEADD(MONTH, -1, GETDATE())

SQL Server SET DATEFIRST scope

I'm using SS 2005 if that
I've seen sample code like
DECLARE #restore = SELECT ##DATEFIRST
SET DATEFIRST 1
SELECT datepart(dw,ADateTimeColumn) as MondayBasedDate,.... FROM famousShipwrecks --
SET DATEFIRST #restore
Suppose while the query is running another query sets DATEFIRST?
If another query relies on datefirst being 7 (for example) and doesn't set it, and runs while my query is running, that's his problem for not setting it? or is there a better way to write queries that depend on a given day being day number 1.
##DATEFIRST is local to your session. You can verify it by opening to tabs in Sql Server Management Studio (SSMS). Execute this code in the first tab:
SET DATEFIRST 5
And verify that it doesn't affect the other tab with:
select ##datefirst
See this MSDN article.
Just an additional point, if you want to avoid setting DATEFIRST you can just incorporate the value of DATEFIRST in your query to find your required day as :
SELECT (datepart(dw,ADateTimeColumn) + ##DATEFIRST) % 7) as 'MondayBasedDate'
, ...
FROM famousShipwrecks --
Then you dont need to worry about restoring it at all!
To setup a parameterized first day of the week, the following should work
DECLARE #FirstDayOfWeek INT = 1;
DECLARE #DateTime DATETIME = '2015-07-14 8:00:00';
SELECT (DATEPART(weekday, #DateTime) + ##DateFirst - #FirstDayOfWeek - 1) % 7 + 1;
You can forget about DATEPART(weekday, DateColumn) and ##DATEFIRST and instead calculate the day of the week yourself.
For Monday based weeks (Europe) simplest is:
SELECT DATEDIFF(day, '17530101', DateColumn) % 7 + 1 AS MondayBasedDay
For Sunday based weeks (America) use:
SELECT DATEDIFF(day, '17530107', DateColumn) % 7 + 1 AS SundayBasedDay
This works fine ever since January 1st respectively 7th, 1753.