Stored Procedure throwing error - sql

I tried to execute this procedure but I am getting error.
I tried to execute using:
execute Currentmonth 20141220
Error:
Msg 208, Level 16, State 1, Procedure Currentmonth, Line 15
Invalid object name 'DimDate'
Why I am getting this error? Can you please tell me the errors in the query for creating stored procedure and what are the parameters I am expecting?
create procedure Currentmonth
#Completeddatekey varchar(20)
as
begin
Getting the current date and formatting it
Declare #currentdate varchar(30)
set #currentdate = convert(Varchar(20), getdate()-1, 101)
print #currentdate
Getting DayofMonth and EndofMonth from DimDate
Declare #dayofmonth int
Declare #endofmonth int
select #dayofmonth = DayofMonth, #endofmonth = EndofMonthDateKey
from bi.dbo.DimDate
where datekey = #currentdate
Getting HierMonthEndKey
declare #hiermonthendkey int
select #hiermonthendkey = MAX(HierMonthEndKey)
from DimHospiceHiearchy
where HierMonthEndKey <= #currentdate+1
Declare #day
For Loop
Declare #i int = 0
declare #startdate varchar(20)
select #startdate = CAST(CAST(YEAR(convert(Varchar(20), getdate()-1, 101)) AS VARCHAR(4))
+ '/' + CAST(MONTH(convert(Varchar(20), getdate()-1, 101)) AS VARCHAR(2)) + '/01' AS DATETIME)+1
While #i <=#dayofmonth
begin
set #startdate = #startdate+#i
exec MA010103 #completeddatekey, #hiermonthendkey
set #i = #i+1
end
end

This error occurs when an object that does not exist is referenced. If the object exists, you might need to include the owner's name in the object name.
Please check the table exists in the mentioned database ?
select #dayofmonth = DayofMonth, #endofmonth = EndofMonthDateKey from
bi.dbo.DimDate
where datekey = #currentdate

Instead of
Declare #dayofmonth int
Declare #endofmonth int
select #dayofmonth = DayofMonth, #endofmonth = EndofMonthDateKey from bi.dbo.DimDate
where datekey = #currentdate
Please try
Declare #dayofmonth int
Declare #endofmonth int
select #dayofmonth = DayofMonth, #endofmonth = EndofMonthDateKey from DimDate
where datekey = #currentdate
Or check if DimDate Table exists

Related

SQL Server: fetching a variable name from a table and assigning value inside the stored procedure

I have some variable name stored in a table, which I need to populate in a stored procedure based on a condition.
For example:
Query: select column1 from TestTable
Output of Query: #FromDate
Now inside the stored procedure, I have the following:
DECLARE #FromDate DATE = '2022-06-01'
DECLARE #QueryResult Varchar(50);
DECLARE #SQLCommand Varchar(50);
SELECT #QueryResult = column1
FROM TestTable
SET #SQLCommand = 'SELECT * FROM emp WHERE joindate >= ''' + #QueryResult + ''';'
EXEC (#SQLCommand);
Now I am expecting that result should be all the employee whose joindate >= '2022-06-01'. Or in other words, I am expecting to use #FromDate variable to fetch data. But when i run query, I get the following error:
Msg 137, Level 15, State 2, Line 1
Must declare the scalar variable "#FromDate"
When I run:
print #SQLCommand;
I get:
select * from emp where joindate >= '#FromDate';
While I am expecting that #FromDate value should be populated here at run time.
Will be thankful for any help regarding this.
Update: actually, there is a loop inside my sp, which fetches the data from table (data contains variable names to be used in the stored procedure in different logic I) like for a particular record: I need to add 20 days in #fromdate, and for another record I need to add 30 days. Now when my loop will run, it will fetch either dateadd(day, 20, #fromdate) or dateadd(day, 30, #fromdate) from table based on where clause and then I need to fill in the value of #fromdate (this is parametrise variable) and fetch the results accordingly.
Update 2:
Please see below my code
USE [GBI_archive]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[sp_Process_Data]
(#StartDate DATE = NULL,
#EndDate DATE = NULL)
AS
DECLARE #FromDate DATE = ISNULL(#StartDate, DATEADD(DAY, 1, EOMONTH(GETDATE(), -1)));
DECLARE #ToDate DATE = ISNULL(#EndDate, GETDATE());
DECLARE #CalculationMethodFromDate VARCHAR(255);
DECLARE #SelectStatement VARCHAR(255);
DECLARE #TableIntoStatement VARCHAR(255);
DECLARE #FromStatement VARCHAR(255);
DECLARE #SQLCommand VARCHAR(255);
DECLARE cursor_product CURSOR FOR
SELECT calculation_method_from_date
FROM [dbo].[Calculation_Method_Configuration];
-- Here output can be DATEADD(DAY, -6, #FromDate) or DATEADD(DAY, -14, #FromDate) or so on
OPEN cursor_product;
FETCH NEXT FROM cursor_product INTO #CalculationMethodFromDate
WHILE ##FETCH_STATUS = 0
BEGIN
PRINT #CalculationMethodFromDate
SET #SelectStatement = 'SELECT CURRENT_TIMESTAMP, * ';
SET #TableIntoStatement = 'INTO [dbo].[Table_For_Function_Output]';
SET #FromStatement = 'FROM [dbo].[EmployeeData] where joindate >= ''' + #CalculationMethodFromDate + ''';'
-- SET #SQLCommand = concat (#SelectStatement , ' ', #TableIntoStatement , ' ', #FromStatement);
PRINT #SQLCommand;
EXEC (#SQLCommand);
FETCH NEXT FROM cursor_product INTO #CalculationMethodFromDate,
END;
CLOSE cursor_product;
DEALLOCATE cursor_product;
GO
Now for anyone iteration of loop, print #SQLCommand shows this (if #CalculationMethodFromDate = 'DATEADD(DAY, -6, #FromDate)') :
SELECT CURRENT_TIMESTAMP, * INTO [dbo].[Table_For_Function_Output] FROM [dbo].[EmployeeData] where joindate >= 'DATEADD(DAY, -6, #FromDate)';
and exec command throws this error:
Msg 137, Level 15, State 2, Line 1
Must declare the scalar variable "#FromDate"
But if I am passing #FromDate = '2022-06-07' as parameter to this sp, my expectations for print #SQLCommand shows is:
SELECT CURRENT_TIMESTAMP, * INTO [dbo].[Table_For_Function_Output] FROM [dbo].[EmployeeData] where joindate >= '2022-06-01';
In short: #FromDate variable coming from database at runtime, should be assigned a value from stored procedure.
You don't need a cursor here, you just need to build one big UNION ALL statement. And you need to pass the #FromDate and #ToDate into the dynamic SQL.
CREATE OR ALTER PROCEDURE [dbo].[sp_Process_Data]
#StartDate DATE = NULL,
#EndDate DATE = NULL
AS
DECLARE #FromDate DATE = ISNULL(#StartDate, DATEADD(DAY, 1, EOMONTH(GETDATE(), -1)));
DECLARE #ToDate DATE = ISNULL(#EndDate, GETDATE());
DECLARE SQLCommand nvarchar(max) = (
SELECT STRING_AGG(N'
SELECT CURRENT_TIMESTAMP, e.*
FROM dbo.EmployeeData e
where e.joindate >= ' + CAST(cm.calculation_method_from_date AS nvarchar(max))
, '
UNION ALL ')
FROM dbo.Calculation_Method_Configuration cm
);
PRINT #SQLCommand;
EXEC sp_executesql
#SQLCommand,
N'#FromDate DATE, #ToDate DATE',
#FromDate = #FromDate,
#ToDate = #ToDate;
go
The design itself is questionable. You should really just have a column which tells you how many days to add, then you can just do
SELECT CURRENT_TIMESTAMP, e.*
FROM dbo.EmployeeData e
JOIN dbo.Calculation_Method_Configuration cm
ON e.joindate >= DATEADD(day, -cm.days, #FromDate);
well actually you could simply use sp_executesql for this.
Simplified sample:
-- demo table:
SELECT DATEADD(day, -7, GETDATE()) [Date] INTO [#demo] UNION ALL SELECT DATEADD(day, 1, GETDATE());
-- demo:
DECLARE #CalculationMethodFromDate NVARCHAR(MAX) = N'DATEADD(DAY, -6, #FromDate)';
DECLARE #FromDate DATE = GETDATE();
DECLARE #SQL NVARCHAR(MAX) = N'SELECT * FROM [#demo] WHERE [Date] >= '+#CalculationMethodFromDate+N';';
EXEC sp_executesql #SQL, N'#FromDate DATE', #FromDate=#FromDate;
--cleanup
drop table [#demo];

table valued function getting working days excluding weekend and holidays

actually the function does not work properly after many tests
for example I've triedSelect * from [dbo].[fn_GetLeaveDays] ('2020-09-24',1,'2020-09-25',1,1,1)
and it should returns only 1 as friday is weekend but it returns 2
could you please assist to find whats wrong in the function
ALTER FUNCTION [dbo].[fn_GetLeaveDays] (#DateFrom datetime2,
#CalendarFunction int,
#DateTo AS datetime2,
#AdjustMode bit,
#AdjustWeekEnds bit,
#AdjustHolidays bit)
RETURNS #tbl table (totaldays int)
AS
BEGIN
IF #DateFrom > #DateTo
BEGIN
DECLARE #T datetime2 = #DateTo,
#F datetime2 = #DateFrom;
SELECT #DateFrom = #T,
#DateTo = #F;
END;
DECLARE #Count AS int = 0,
#Date AS datetime2 = #DateFrom;
WHILE #Date < #DateTo
BEGIN
IF ((DATEPART(WEEKDAY, #Date) IN (6)
AND #AdjustWeekEnds = 1)
OR EXISTS (SELECT *
FROM [C3DCalendar].[dbo].[PRIMAVERA_CALENDAR_HOLIDAYS]
WHERE holiday_date = #Date
AND calendar_key = #CalendarFunction
AND #AdjustHolidays = 1))
BEGIN
SELECT #Count = #Count + 1;
END;
SELECT #Date = DATEADD(DAY, 1, #Date);
END;
INSERT INTO #tbl
SELECT (DATEDIFF(DAY, #DateFrom, #DateTo) - (#Count)) + #AdjustMode;
RETURN;
END;

Trying to set default param value in stored procedure but errors on CONVERT

Wish to set default value in stored procedure but running into error, CONVERT doesn't seem to exist. CONVERT works in the body but not in the params section of the stored procedure. How do I set param #StartDate to a default of 24 months in the past?
CREATE PROCEDURE [dbo].[MyStoredProc]
#Id INT = NULL,
#startDate DATETIME = CONVERT(DATE, DATEADD(MONTH, -1 * 24, GETDATE())), -- last 24 months
#endDate DATETIME = CONVERT(DATE, GETDATE())
AS
BEGIN
SELECT #startDate;
END
GO
That works!
CREATE procedure [dbo].[MyStoredProc]
#Id int = null
,#startDate datetime = null
,#endDate datetime = null
as
begin
SET #startDate = ISNULL(#startDate, CONVERT(DATE, DATEADD(MONTH, -1*24, GETDATE())));
select #startDate;
END
GO

Setting default parameters for a SQL Server stored procedure

I am trying to set the default value of #Day to the current day. However, I am getting a couple errors on the initial DATEADD(Day, DATEDIFF(Day, 0, GETDATE()), 0) and on all the #Days below it. I thought that the #Day DateTime under the alter procedure declared #Day but I am getting the error:
Must declare the scalar variable "#Day"
Anyone know what to do?
ALTER PROCEDURE [dbo].[InsertWeeklyRuns]
#Day DateTime = DATEADD(Day, DATEDIFF(Day, 0, GETDATE()), 0)
AS
BEGIN
SET NOCOUNT ON
DECLARE #Enddate DATETIME
DECLARE #StartDate DATETIME
DECLARE #F1Runs INT
DECLARE #F2Runs INT
DECLARE #F3Runs INT
DECLARE #F1Alarms INT
DECLARE #F2Alarms INT
DECLARE #F3Alarms INT
SET #Day = DATEADD(dd, DATEDIFF(dd, 0, #Day), 0)
SET #Enddate = CASE
WHEN #Day > DATEADD(Day, DATEDIFF(Day, 0, GETDATE()), 0)
THEN DATEADD(Day, DATEDIFF(Day, 0, GETDATE()), 0)
ELSE DATEADD(Day, 1, #Day)
END
SET #StartDate = #Enddate - 7
Thanks
This should work as you expected:
CREATE PROCEDURE [dbo].[InsertWeeklyRuns]
#Day DateTime
AS
BEGIN
SET NOCOUNT ON
Declare #Enddate Datetime
Declare #StartDate Datetime
Declare #F1Runs Int
Declare #F2Runs Int
Declare #F3Runs Int
Declare #F1Alarms Int
Declare #F2Alarms Int
Declare #F3Alarms Int
DECLARE #today date = CAST(GETDATE() AS date);
IF #Day IS NULL
Set #Day = #today
Set #Enddate = CASE WHEN #Day >= #today THEN #today ELSE DATEADD(Day, 1, #Day) END
Set #StartDate = #Enddate - 7
END

SQL: How to produce next date given month and day

In my table I have a Month(tinyint) and a Day(tinyint) field. I would like to have a function that takes this month and day and produces a datetime for the next date(including year) given this month and day.
So if I had Month = 9, Day = 7 it would produce 9/7/2009.
If I had Month 1, Day 1 it would produce 1/1/2010.
something like this would work. It's variation on your method, but it doesn't use the MM/DD/YYYY literal format, and it won't blowup against bad input (for better or for worse).
declare #month tinyint
declare #day tinyint
set #month = 9
set #day = 1
declare #date datetime
-- this could be inlined if desired
set #date = convert(char(4),year(getdate()))+'0101'
set #date = dateadd(month,#month-1,#date)
set #date = dateadd(day,#day-1,#date)
if #date <= getdate()-1
set #date = dateadd(year,1,#date)
select #date
Alternatively, to create a string in YYYYMMDD format:
set #date =
right('0000'+convert(char(4),year(getdate())),4)
+ right('00'+convert(char(2),#month),2)
+ right('00'+convert(char(2),#day),2)
Another method, which avoids literals all together:
declare #month tinyint
declare #day tinyint
set #month = 6
set #day = 24
declare #date datetime
declare #today datetime
-- get todays date, stripping out the hours and minutes
-- and save the value for later
set #date = floor(convert(float,getdate()))
set #today = #date
-- add the appropriate number of months and days
set #date = dateadd(month,#month-month(#date),#date)
set #date = dateadd(day,#day-day(#date),#date)
-- increment year by 1 if necessary
if #date < #today set #date = dateadd(year,1,#date)
select #date
Here is my sql example so far. I don't really like it though...
DECLARE #month tinyint,
#day tinyint,
#date datetime
SET #month = 1
SET #day = 1
-- SET DATE TO DATE WITH CURRENT YEAR
SET #date = CONVERT(datetime, CONVERT(varchar,#month) + '/' + CONVERT(varchar,#day) + '/' + CONVERT(varchar,YEAR(GETDATE())))
-- IF DATE IS BEFORE TODAY, ADD ANOTHER YEAR
IF (DATEDIFF(DAY, GETDATE(), #date) < 0)
BEGIN
SET #date = DATEADD(YEAR, 1, #date)
END
SELECT #date
Here's a solution with PostgreSQL
your_date_calculated = Year * 10000 + Month * 100 + Day
gives you a date like 20090623.
select cast( cast( your_date_calculated as varchar ) as date ) + 1
Here's my version. The core of it is just two lines, using the DATEADD function, and it doesn't require any conversion to/from strings, floats or anything else:
DECLARE #Month TINYINT
DECLARE #Day TINYINT
SET #Month = 9
SET #Day = 7
DECLARE #Result DATETIME
SET #Result =
DATEADD(month, ((YEAR(GETDATE()) - 1900) * 12) + #Month - 1, #Day - 1)
IF (#Result < GETDATE())
SET #Result = DATEADD(year, 1, #Result)
SELECT #Result