I run an "Execute SQL Task" in SSIS
It runs a stored procedure which does some validation
In the Stored Procedure I have a RAISERROR command when something goes wrong.
However when I test for this, this task fails to abort.
I have Googled about this and found lots of references, but no solution that works for me.
I have upgraded my SQL Server 2005 to service pack 3, but this does not make any difference.
One reference suggests putting in PRINT statements when an exception is thrown, This does not work.
So how do I fix this?
The code in the stored procedure is;
ALTER PROCEDURE [dbo].[usp_VAL_Journey]
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE #Month AS INT
, #Year AS INT
SELECT TOP 1 #Year = DATEPART(YEAR, Date), #Month = DATEPART(MONTH, Date)
FROM dbo.JourneyLandingTable
SELECT TOP 1 *
FROM dbo.JourneyMasterTable
WHERE DATEPART(YEAR, Date) = #Year
AND DATEPART(MONTH, Date) = #Month
IF ##ROWCOUNT > 0
BEGIN
RAISERROR('JourneyMasterTable already contains data for this month.', 16, 1)
RETURN
END
SELECT DATEPART(YEAR, Date) AS year1, DATEPART(MONTH, Date) AS month1
FROM dbo.JourneyLandingTable
GROUP BY DATEPART(YEAR, Date), DATEPART(MONTH, Date)
IF ##ROWCOUNT > 1
BEGIN
RAISERROR('JourneyLandingTable contains data for more than 1 month.', 16, 1)
END
END
I have a similar thing but works fine for me. Not sure why it doesnt. The setup I have is I dont raiseerror at various places. I keep incrementing the error count and finally raise it as follows. It works perfectly - it aborts execution and all that good stuff.
declare #errorString varchar(100)
IF #rc > 0
BEGIN
set #errorString = 'Error(s) occured when trying to run sp_blahblah error count ' + cast(#rc as varchar(10))
raiserror(#errorString , 16, 1)
END
you might want to try returning some value "RETURN n"
ALTER PROCEDURE [dbo].[usp_VAL_Journey]
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE #Month AS INT
, #Year AS INT
SELECT TOP 1 #Year = DATEPART(YEAR, Date), #Month = DATEPART(MONTH, Date)
FROM dbo.JourneyLandingTable
SELECT TOP 1 *
FROM dbo.JourneyMasterTable
WHERE DATEPART(YEAR, Date) = #Year
AND DATEPART(MONTH, Date) = #Month
IF ##ROWCOUNT > 0
BEGIN
RAISERROR('JourneyMasterTable already contains data for this month.', 16, 1)
RETURN 10 --<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
END
SELECT DATEPART(YEAR, Date) AS year1, DATEPART(MONTH, Date) AS month1
FROM dbo.JourneyLandingTable
GROUP BY DATEPART(YEAR, Date), DATEPART(MONTH, Date)
IF ##ROWCOUNT > 1
BEGIN
RAISERROR('JourneyLandingTable contains data for more than 1 month.', 16, 1)
RETURN 20 --<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
END
END
you should be able to tell if that code block was hit by checking the procedure's return value.
Related
I am trying to Create a view where i need to put condition on year and I am trying below code but I get an error. Can someone please suggest if its possible . And the output which is required I have to use CTE only.
Error is as below : incorrect Syntax near ‘if’
Code is as below :
Declare #year varchar(20)
Set #year = ‘2022’;
With CTE as
(
If #year = ‘2022’
Begin
(
Select
#year ,
Prev_date = (select DATEADD(month, -1,GETDATE()))
)
End;
Else
Begin
(
Select #year,
Prev_date= (select DATEADD(month, -2,GETDATE()))
)
End;
)
Select *
From CTE
I'm not entirely sure what you want to achieve with your cte, but concerning the condition, you can try to put the following into your view / query / whatever:
Declare #year varchar(20)
Set #year = '2022';
SELECT [year] = #year, [prev_date] = DATEADD(month, -1 * CASE WHEN #year = '2022' THEN 1 ELSE 2 END, GETDATE())
IF, BEGIN and END are related to the procedural code, and cannot be used in this context.
Your code, without further specification, can be replaced with the following:
DECLARE #Year varchar(20);
SET #Year = '2022';
WITH CTE AS
(
SELECT Year = #year,
PrevDate = DATEADD(month, -1,GETDATE())
)
SELECT *
FROM CTE;
A note and a piece of advice: it looks (am I wrong?) that you are at the beginning of the learning. Try to keep coding guidelines for SQL Server, please. I have made some quick improvements. An example link to follow: https://blog.sqlauthority.com/2008/09/25/sql-server-guidelines-and-coding-standards/
You can use simple effective query rather than going for CTE which should be used for complex queries.
Declare #year varchar(20) Set #year = '2023';
select #year [Year], prev_date = case when #year='2022' then (Select DATEADD(month, -1,GETDATE())) else DATEADD(month, -2,GETDATE()) end
You have not give the error and what database you are using.
I suppose you sql should be syntax error, please try this
Declare #year varchar(20)
Set #year = ‘2022’
With CTE as
(
If #year = ‘2022’
Begin
{
Select
#year ,
(select DATEADD(month, -1,GETDATE())) as previous_date
}
END;
)
Select *
From CTE
BEGIN ... END; must use with {..} in the case use have multiple statments in between.
Hope this help.
This function returns a single date and not a list of 61 dates as expected. Any ideas what I am doing wrong?
alter FUNCTION udf_foo()
RETURNS #Result TABLE
(
days datetime
)
AS
begin
DECLARE #i int = -1
begin
WHILE #i < 60
SET #i = #i + 1
INSERT into #Result select dateadd (day, -#i, getdate())
end ;
return;
end
Like you wrote it, the body of the WHILE loop only spans the next statement.
You only get one result because the INSERT isn't part of the loop's body and it only executed once (after the loop incremented #i to 60).
If you want to have a body of more than one statement, enclose the statements in a BEGIN ... END block.
...
WHILE #i < 60
BEGIN
SET #i = #i + 1;
INSERT INTO #Result
SELECT dateadd(day, -#i, getdate());
END;
...
You can just use a CTE for this:
with dates as (
select cast(getdate() as date) as dte
union all
select dateadd(day, -1, dte)
from dates
where dte >= dateadd(day, -60, getdate())
)
select *
from dates;
You hardly need a function for this, although you could put this in a function if you really wanted to.
Here is an example of incorporating this into a view.
I'm trying to insert yearly weekend details such as date, dayName into a SQL Server table using the following stored procedure
alter procedure usp_AddOfficeHolidays
#paramName NVARCHAR(max)
as
begin
DECLARE #Year AS INT,
#FirstDateOfYear DATETIME,
#LastDateOfYear DATETIME
-- You can change #year to any year you desire
SELECT #year = 2016
SELECT #FirstDateOfYear = DATEADD(yyyy, #Year - 1900, 0)
SELECT #LastDateOfYear = DATEADD(yyyy, #Year - 1900 + 1, 0)
-- Creating Query to Prepare Year Data
--declare dayN varchar(max)
if (select COUNT(*) from tblWeekSettings) < 1
begin
;WITH cte AS
(
SELECT
1 AS DayID,
#FirstDateOfYear AS FromDate,
DATENAME(dw, #FirstDateOfYear) AS Dayname
UNION ALL
SELECT
cte.DayID + 1 AS DayID,
DATEADD(d, 1 ,cte.FromDate),
DATENAME(dw, DATEADD(d, 1 ,cte.FromDate)) AS Dayname
FROM cte
WHERE DATEADD(d, 1, cte.FromDate) < #LastDateOfYear
)
SELECT FromDate AS Date, Dayname
FROM CTE
WHERE DayName IN (SELECT Param FROM dbo.fn_MVParam(#paramName,','))
OPTION (MaxRecursion 370)
end
else
begin
Select 'Exists'
end
end
and executing it using
exec usp_AddOfficeHolidays 'Saturday,Sunday'
which returns the following result
This works perfectly fine, BUT I have been unable to add/insert these details into the following table
I face the following error when I try to access the WEEKEND details by its alias CTE
The statement terminated. The maximum recursion 100 has been exhausted
before statement completion
Although I've added the clause
OPTION (MaxRecursion 370)
suggested by these links which I found on stack overflow
The maximum recursion 100 has been exhausted before statement completion
The statement terminated. The maximum recursion 100 has been exhausted before statement completion
EDIT
Basically i face the specified error when i try something like this
alter procedure usp_AddOfficeHolidays
#paramName NVARCHAR(max)
as
begin
----------------------------------------------------------
DECLARE #Year AS INT,
#FirstDateOfYear DATETIME,
#LastDateOfYear DATETIME
-- You can change #year to any year you desire
SELECT #year = 2016
SELECT #FirstDateOfYear = DATEADD(yyyy, #Year - 1900, 0)
SELECT #LastDateOfYear = DATEADD(yyyy, #Year - 1900 + 1, 0)
-- Creating Query to Prepare Year Data
--declare dayN varchar(max)
if (select COUNT(*) from tblWeekSettings) < 1
begin
;WITH cte AS (
SELECT 1 AS DayID,
#FirstDateOfYear AS FromDate,
DATENAME(dw, #FirstDateOfYear) AS Dayname
UNION ALL
SELECT cte.DayID + 1 AS DayID,
DATEADD(d, 1 ,cte.FromDate),
DATENAME(dw, DATEADD(d, 1 ,cte.FromDate)) AS Dayname
FROM cte
WHERE DATEADD(d,1,cte.FromDate) < #LastDateOfYear
)
SELECT FromDate AS Date, Dayname
FROM CTE
WHERE DayName IN(SELECT Param FROM dbo.fn_MVParam(#paramName,','))
insert into tblWeekSettings(DayNo,WeekDayName,Dates)
values('',Dayname,Date)
OPTION (MaxRecursion 370)
end
else
begin
Select 'Exists'
end
--select cte
-----------------------------------------------------------
end
Any sort of help here would really be appreciated! I just need to insert the data in my the specified table!
Thank you!
That's the error:
SELECT FromDate AS Date, Dayname
FROM CTE
WHERE DayName IN(SELECT Param FROM dbo.fn_MVParam(#paramName,','))
I split this code to make you understand what code actually is working in this case:
insert into tblWeekSettings(DayNo,WeekDayName,Dates)
values('',Dayname,Date)
OPTION (MaxRecursion 370)
OPTION (MAX RECURSION) now belongs to single insert statement. Which is standalone, totally not related to CTE.
You actually need this, I suppose:
;with CTE (...)
insert into tblWeekSettings(DayNo,WeekDayName,Dates)
SELECT FromDate AS Date, Dayname
FROM CTE
WHERE DayName IN(SELECT Param FROM dbo.fn_MVParam(#paramName,','))
OPTION (MaxRecursion 370)
but there are three columns in target table whilst your select has only two columns. So you'll have to update your select.
Some tips about INSERT-SELECT:
http://www.w3schools.com/sql/sql_insert_into_select.asp
this code:
insert into tblWeekSettings(DayNo,WeekDayName,Dates)
values('',Dayname,Date)
does not have any source for inserting. This is not valid code - you don't have here any Dayname,Date variables - they are not even referenced with # as variables. It's totally not valid code.
For anyone who face the following issues
Getting Weeked details i.e. DayName, Date
Inserting into a Table
This stored procedure would do the trick.
alter procedure usp_AddOfficeHolidays
#paramName NVARCHAR(max)
as
begin
----------------------------------------------------------
DECLARE #Year AS INT,
#FirstDateOfYear DATETIME,
#LastDateOfYear DATETIME
-- You can change #year to any year you desire
SELECT #year = 2016
SELECT #FirstDateOfYear = DATEADD(yyyy, #Year - 1900, 0)
SELECT #LastDateOfYear = DATEADD(yyyy, #Year - 1900 + 1, 0)
-- Creating Query to Prepare Year Data
--declare dayN varchar(max)
if (select COUNT(*) from tblWeekSettings) < 1
begin
;WITH cte AS (
SELECT 1 AS DayID,
#FirstDateOfYear AS FromDate,
DATENAME(dw, #FirstDateOfYear) AS Dayname
UNION ALL
SELECT cte.DayID + 1 AS DayID,
DATEADD(d, 1 ,cte.FromDate),
DATENAME(dw, DATEADD(d, 1 ,cte.FromDate)) AS Dayname
FROM cte
WHERE DATEADD(d,1,cte.FromDate) < #LastDateOfYear
)
insert into tblWeekSettings(DayNo,Dates,WeekDayName)
SELECT '',FromDate AS Date, Dayname
FROM CTE WHERE DayName IN(SELECT Param FROM dbo.fn_MVParam(#paramName,','))
OPTION (MaxRecursion 30000)
end
else
begin
Select 'Exists'
end
--select cte
-----------------------------------------------------------
end
Plus this article could really be helpful.
http://www.w3schools.com/sql/sql_insert_into_select.asp
Try this, I hope this is useful for you.
alter procedure usp_AddOfficeHolidays
#paramName NVARCHAR(max)
as
begin
----------------------------------------------------------
DECLARE #Year AS INT,#DayNo as int=1,
#FirstDateOfYear DATETIME,
#LastDateOfYear DATETIME
-- You can change #year to any year you desire
SELECT #year = 2016
SELECT #FirstDateOfYear = DATEADD(yyyy, #Year - 1900, 0)
SELECT #LastDateOfYear = DATEADD(yyyy, #Year - 1900 + 1, 0)
Select getdate() DateOfYear into #tbl where 1=0
-- Creating Query to Prepare Year Data
--declare dayN varchar(max)
if (select COUNT(*) from tblWeekSettings) < 1
begin
while (#FirstDateOfYear< #LastDateOfYear)
begin
Insert Into #tbl (DayNo,DateOfYear) values (#DayNo,#FirstDateOfYear)
set #FirstDateOfYear+=1
set #DayNo+=1;
End
Insert Into tblWeekSettings (DayNo,WeekDayName,Dates)
SELECT DayNo,DATENAME(dw, DateOfYear) Name,DateOfYear AS Date
FROM #tbl
WHERE DATENAME(dw, DateOfYear) IN(SELECT Param FROM dbo.fn_MVParam(#paramName,','))
end
else
begin
Select 'Exists'
end
--select cte
-----------------------------------------------------------
end
I know that there are other posts with code that solve my problem but I don't want to take another's code so I'm trying to do it by myself and I'm stuck with the month not increasing problem, so if anyone can help me with that mistake it will be awesome.
The problem is:
I have to populate the table Time from year 1990 to 2016 with all the months and days, I have already achieved that the code works and it populates correctly the years and the days but months increases to January (1) and then is not increasing so the table is filled with all months being January (LOL)
Here's my code:
create table Time
(
Year int,
Month int,
Day int
)
create procedure pTime
as
declare #year int, #month int, #day int;
set #year = 1990;
set #month = 12;
set #day = 10;
while(#year<=2016)
Begin
If(#day = 29)
Begin
set #month = #month + 1;
If(#month = 13)
Begin
set #month = 1;
set #day = 1;
set #year = #year + 1;
insert into Time values (#year, #month, #day);
End
End
else
Begin
If(#day = 29)
Begin
set #month = #month + 1;
set #day = 1;
insert into Time values (#year, #month, #day);
End
Else
Begin
insert into Time values (#year, #month, #day);
set #day = #day + 1;
End
End
End
Any idea where is my mistake or any suggestion?
I didn't look very closely for your mistake because SQL Server has some helpful date arithmetic functions. Here's simplified version of your stored procedure:
create procedure pTime
as
declare #theDate date = '12/10/1990', #days int = 0
while #theDate < '1/1/2016'
begin
insert into Time (Year, Month, Day) values (datepart(year, #theDate), datepart(month, #theDate), datepart(day, #theDate));
set #theDate = dateadd(day, 1, #theDate)
end
Another faster approach would be to use a tally table. Note the code below:
WITH
E(N) AS (SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1),
iTally(N) AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 1))-1 FROM E a,E b,E c,E d,E e),
dates(dt) AS
(
SELECT TOP(datediff(DAY,'19900101','20160101')) DATEADD(day,N,'19900101')
FROM iTally
)
--INSERT [time] --uncomment for the insert, leave commented to see what will be inserted
SELECT YEAR(dt), MONTH(dt), DAY(dt)
FROM dates;
Why do you need If(#year = 29) condition? In your code this block never will be executed. try this:
create procedure pTime
as
declare #year int, #month int, #day int;
set #year = 1990;
set #month = 12;
set #day = 10;
while(#year<=2016)
Begin
If(#day = 29)
Begin
set #month = #month + 1;
set #day = 1;
If(#month = 13)
Begin
set #month = 1;
set #year = #year + 1;
insert into Time values (#year, #month, #day);
End
End
else
Begin
If(#day = 29)
Begin
set #month = #month + 1;
set #day = 1;
insert into Time values (#year, #month, #day);
End
Else
Begin
insert into Time values (#year, #month, #day);
set #day = #day + 1;
End
End
End
I think first assignment set #day = 1; wasn't in right place. After increasing #month value you should set also #day to 1;
I need to execute a stored procedure at the end of each calendar month. it should take end of the current month as finish and end of previous month as start date.
Here examples:
exec my_report #ReportStartDate = '20140731', #ReportEndDate='20140831'
exec my_report #ReportStartDate = '20140131', #ReportEndDate='20131231'
exec my_report #ReportStartDate = '20140228', #ReportEndDate='20140131'
My aim is to store results in a table. So I need to create a new stored procedure to call the current stored procedure.
I could not find to schedule the my_report stored procedure. So I create a new stored procedure. My aim is to call caller_sp on each day and check the dates inside the caller stored procedure.
Here my caller stored procedure. I have good knowledge of oracle but I an new to SQL Server.
Is there a way to schedule my_report at the end of each calendar month and send begin and end dates.
Is there a decent version of my code below
Code:
declare #reportstartyear VARCHAR(4) = null
declare #ReportEndDate DATETIME = null
declare #ReportStartDate DATETIME = null
if month(getdate()) = '01'
Begin
if DAY(getdate()) = '31'
Begin
set #reportstartyear = year(getdate())-1
set #ReportStartDate = cast(#reportstartyear + '1231' as Datetime)
exec [LTR].[LetterOfGuaranteeProceedsReport]
#ReportStartDate, #ReportEndDate = cast(select getdate())
end
end
else if month(getdate())='02'
begin
if year(getdate())%4=0
begin
if day(getdate())='29'
begin
set #reportstartyear=year(getdate())
set #ReportStartDate=cast(#reportstartyear+'0131' as Datetime)
exec [LTR].[LetterOfGuaranteeProceedsReport] #ReportStartDate,#ReportEndDate=cast(select getdate())
end
end
end
else if day(getdate())='28'
begin
set #reportstartyear=year(getdate())
set #ReportStartDate=cast(#reportstartyear+'0131' as Datetime)
exec [LTR].[LetterOfGuaranteeProceedsReport] #ReportStartDate,#ReportEndDate=cast(select getdate())
end
else if month(getdate())='03'
begin
if day(getdate())='31'
begin
if year(getdate())%4=0
begin
set #reportstartyear=year(getdate())
set #ReportStartDate=cast(#reportstartyear+'0229' as Datetime)
exec [LTR].[LetterOfGuaranteeProceedsReport] #ReportStartDate,#ReportEndDate=cast(select getdate())
end
else
begin
set #reportstartyear=year(getdate())
set #ReportStartDate=cast(#reportstartyear+'0228' as Datetime)
exec [LTR].[LetterOfGuaranteeProceedsReport] #ReportStartDate,#ReportEndDate=cast(select getdate())
end
end
end
Your script seems a bit complicated
DECLARE #ReportStartDate date, #ReportEndDate date
-- for sqlserver 2012
SELECT
#ReportStartDate = EOmonth(getdate(), -1),
#ReportEndDate = EOmonth(getdate())
-- for earlier versions
SELECT
#ReportStartDate = dateadd(month, datediff(m, 0, getdate()), -1),
#ReportEndDate = dateadd(month, datediff(m, -1, getdate()), -1)
EXEC my_report #ReportStartDate, #ReportEndDate
To execute the job the last day of every month:
Create a job, then find and pick
Under frequency:
Occurs: Monthly
The Last - Day - of every 1 month
Here my script. I changed to a SP. It works fine. Thanks every one
declare
#ReportStartDate DATETIME=EOmonth(getdate(), -1),
#ReportEndDate DATETIME=EOmonth(getdate())
if #ReportEndDate=getdate()
Begin
insert into report_log (col1,
col2,
col3
) exec Report #ReportStartDate, #ReportEndDate,#username=null,#LanguageId=null
update report_log set reportstartdate=#ReportStartDate, reportenddate=#ReportEndDate where reportenddate is null
end
You can simplify it a lot.
If you're using a modern SQL Server, you have the EOMONTH function, to get the last day of the month.
If your SQL Server is older, you can do a little trick: use DATEADD function to add 1 day to the current deta (getdate()), and compare the month (using the MONTH function). If it's the same month, it wasn't the last day of the month. If it's a different month, that's because it was the last day of the month.
References:
EOMONTH
DATEADD
MONTH
I am surely late for this question and I may post the answer out of the context a little bit. But as #JotaBe said (in older version in my case) you can know if you are in new month (In case you have script that run reports of month -1) in this simple way.
declare #cDate as date = getDate(), #comDate as Date;
set #comDate = DATEADD(day, -1, #cDate)
if DATEPART(MONTH, #cDate) > DATEPART(month, #comDate)
print 'Different month'
else
print 'same month'
Inside the if you can fine tune to whatever you want (steps in jobs, etc)