SQL SERVER - Need a Simple T-SQL Program to iterate date - sql

My procedure that I am calling works on day by day basis. I need to pass/iterate by one day upto the current date to the procedure for it to perform the action. Can some help with that. Here is the sample that I tried but it fails to work. I am beginner.
USE [aaa]
GO
DECLARE #return_value int
DECLARE #VarDate1 Datetime ='2015-09-30'
DECLARE #VarDate2 Datetime ='2015-09-30'
WHILE (#VarDate2 <= '2015-12-10')
BEGIN
EXEC #return_value = [dbo].[procname]
#tday1 = #VarDate1 ,
#tday2 = #VarDate2
SET #VarDate2 = DATEADD(DAY, 1, #VarDate2)
set #VarDate1 = #VarDate2
SELECT 'Return Value' = #return_value
END
GO

By checking your code, you're probably getting an error while trying to set the value for #VarDate1 and #VarDate2. Try the code below:
DECLARE #return_value int
DECLARE #VarDate1 Datetime = CAST('20150930 00:00:00' AS DATETIME)
DECLARE #VarDate2 Datetime = CAST('20150930 00:00:00' AS DATETIME)
WHILE (#VarDate2 <= '20151210') BEGIN
SET #VarDate2 = DATEADD(DAY, 1, #VarDate2)
SET #VarDate1 = #VarDate2
PRINT #VarDate2 --Change your logic here
END
GO

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];

SQL Server : combine 2 stored procedures into one

I have 2 stored procedures, and my goal is to combine these into one so
I can use filter to select value CHOOSE.
Thank you.
EXEC dbo.newcombine #startdate = 'yyyy-mm-dd', #enddate = 'yyyy-mm-dd', #choose = 'testone' OR #choose = 'testwo'
First stored procedure:
#choose nvarchar(10)
set #choose = testone
#startdate date
,#enddate date
AS
BEGIN
SET NOCOUNT ON;
SELECT
c.TypeofCall
FROM
Contact c
AND c.callin BETWEEN #startdate AND #enddate
END
Second stored procedure:
#choose nvarchar(10)
set #choose = testtwo
#startdate date
,#enddate date
AS
BEGIN
SET NOCOUNT ON;
SELECT
c.TypeofService
FROM
Contact c
AND c.callin BETWEEN #startdate AND #enddate
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

Issue while calculating SLA in SQL

I am using below function to calculate the elapsed time between 2 input timestamps. Only time spent during business hours should be calculated. Business hrs are Mon-Sat 8 am to 6 pm.
Function call syntax:
select xxxxx('2018.09.28 19:02:28','2018-09-29 10:40:35') Function is giving output as 98 mins, the correct answer is 160 mins.
Function structure is:
Create FUNCTION xxxxx (#LeadAssignTime DATETIME, #LeadContactTime DATETIME)
RETURNS VARCHAR(9)
AS
BEGIN
DECLARE #Temp BIGINT
SET #Temp=0
DECLARE #LeadAssignDay VARCHAR(9)
SET #LeadAssignDay = CONVERT(VARCHAR(9),#LeadAssignTime, 112)
DECLARE #LeadContactDay VARCHAR(9)
SET #LeadContactDay = CONVERT(VARCHAR(9),#LeadContactTime, 112)
DECLARE #StartTime VARCHAR(9)
SET #StartTime = CONVERT(VARCHAR(9),#LeadAssignTime, 108)
DECLARE #FinishTime VARCHAR(9)
SET #FinishTime = CONVERT(VARCHAR(9),#LeadContactTime, 108)
DECLARE #WorkStart VARCHAR(9)
SET #WorkStart = '08:00:00'
DECLARE #WorkFinish VARCHAR(9)
SET #WorkFinish = '18:00:00'
IF (#StartTime<#WorkStart)
BEGIN
SET #StartTime = #WorkStart
END
IF (#FinishTime>#WorkFinish)
BEGIN
SET #FinishTime=#WorkFinish
END
DECLARE #CurrentDate VARCHAR(9)
SET #CurrentDate = CONVERT(VARCHAR(9),#LeadAssignTime, 112)
DECLARE #LastDate VARCHAR(9)
SET #LastDate = CONVERT(VARCHAR(9),#LeadContactTime, 112)
WHILE(#CurrentDate<=#LastDate)
BEGIN
IF (DATEPART(dw, #CurrentDate)!=1 )
BEGIN
IF (#CurrentDate!=#LeadAssignDay) AND (#CurrentDate!=#LeadContactDay)
BEGIN
SET #Temp = (#Temp + (8*60))
END
ELSE IF (#CurrentDate=#LeadAssignDay) AND (#CurrentDate!=#LeadContactDay)
BEGIN
SET #Temp = #Temp + DATEDIFF(MINUTE, #StartTime, #WorkFinish)
END
ELSE IF (#CurrentDate!=#LeadAssignDay) AND (#CurrentDate=#LeadContactDay)
BEGIN
SET #Temp = #Temp + DATEDIFF(MINUTE, #WorkStart, #FinishTime)
END
ELSE IF (#CurrentDate=#LeadAssignDay) AND (#CurrentDate=#LeadContactDay)
BEGIN
SET #Temp = DATEDIFF(MINUTE, #StartTime, #FinishTime)
END
END
SET #CurrentDate = CONVERT(VARCHAR(9),DATEADD(day, 1, #CurrentDate),112)
END
Return #TEMP
END
You're going around your loop twice, but in the first iteration, you fall into the second IF block and setting #temp to be -62
In the second iteration, you fall into the third IF block and calculate 160 for the difference between #WorkStart and #FinishTime, but then this is added to the value already in #Temp. 160-62 = 98.
You'll need your second IF block to check if 'start time' is before 'work finish' before executing that logic.
(#CurrentDate=#LeadAssignDay) AND (#CurrentDate!=#LeadContactDay)
needs to become
(#CurrentDate=#LeadAssignDay) AND (#CurrentDate!=#LeadContactDay) AND ( #StartTime < #WorkFinish)
I haven't done any vetting beyond the one use case. Make sure to do some thorough testing.

How do I select any value from SP?

I have SP like :
CREATE PROCEDURE MySP
(
#startdate datetime = null,
#enddate datetime = null
)
AS
BEGIN
declare #date datetime
Set #date= convert(datetime,convert(varchar(10),getdate(),101))
SET #startdate = ISNULL(#startdate,convert (datetime,convert(varchar(10),getdate(),101)))
select #startdate -- i want to select and view this value
END
GO
I want to view select #startdate value, How can i do this?
You execute the stored procedure.
exec MySP
Result:
(No column name)
2011-08-10 00:00:00.000
Edit
Stored procedure with output parameter #startdate
alter PROCEDURE MySP
(
#startdate datetime = null out,
#enddate datetime = null
)
AS
BEGIN
declare #date datetime
Set #date= convert(datetime,convert(varchar(10),getdate(),101))
SET #startdate = ISNULL(#startdate,convert (datetime,convert(varchar(10),getdate(),101)))
END
Use like this
declare #D datetime
exec MySP #D out
select #D