Fred Webb
asked on
Using a SUBQUERY for the set variable
I am having a bit of a problem, I have a function that generates a next date based on a variable for example it will generate a date that is say 254 days from a specific date which I want to be a parameter. so... if I run it with a fixed value it returns the proper date
But I need it to give me a date for each parameter value for IV00102.LSTCNTDT as i will want that value use to update another table Column. but it is giving me the following error
Msg 512, Level 16, State 1, Line 2
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
select dbo.getNextBusinessDay(CONVERT(DATE, '2017-05-09', 102), 254) as NextDay
But I need it to give me a date for each parameter value for IV00102.LSTCNTDT as i will want that value use to update another table Column. but it is giving me the following error
Msg 512, Level 16, State 1, Line 2
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
DECLARE @LSTCNTDT datetime
SET @LSTCNTDT = (SELECT IV00102.LSTCNTDT FROM IV00102 WHERE (LOCNCODE = 'CENTRAL') AND (LSTCNTDT <> CONVERT(DATETIME, '1900-01-01 00:00:00', 102)))
select dbo.getNextBusinessDay(CONVERT(DATE, @LSTCNTDT, 102), 254) as NextDay
ASKER
because the date is not a static value there are different dates that the that the 254 days need to be applied to. Yes it pulls data from a calendar table.
create function getNextBusinessDay(@date date, @n int) returns date as
begin
declare @nd date = dateadd(day, @n, @date);
select @nd = calDate from (
select calDate, row_number() over(order by calDate) rn from calendar c
where c.CalDate>@date and isHoliday=0 and isWeekend=0
) x where rn=@n;
return @nd;
end;
No, what I mean is why convert the date in the query each time when you can put that in the function?
So you only have to type select dbo.getNextBusinessDay('20 17-05-09', 254) as NextDay
Can you provide information on what the other tables look like?
If you just run the query:
SELECT IV00102.LSTCNTDT FROM IV00102 WHERE (LOCNCODE = 'CENTRAL') AND (LSTCNTDT <> CONVERT(DATETIME, '1900-01-01 00:00:00', 102))
What does it return?
alter function getNextBusinessDay(@datevc varchar(50), @n int) returns date as
begin
declare @date date, @nd date;
SET @date = (SELECT CONVERT(DATE,@datevc,102))
SET @nd = (SELECT dateadd(day, @n, @date))
select @nd = calDate from (
select calDate, row_number() over(order by calDate) rn from calendar c
where c.CalDate>@date and isHoliday=0 and isWeekend=0
) x where rn=@n;
return @nd;
end;
So you only have to type select dbo.getNextBusinessDay('20
Can you provide information on what the other tables look like?
If you just run the query:
SELECT IV00102.LSTCNTDT FROM IV00102 WHERE (LOCNCODE = 'CENTRAL') AND (LSTCNTDT <> CONVERT(DATETIME, '1900-01-01 00:00:00', 102))
What does it return?
ASKER
Oh... Got it. the point is though i dont want to type a date i wan to have a parameter pass the date. it returns the the dates for the last count date. I have updated the query to just return distinct dates. my end goal is to use the date returned to update another column.
(SELECT DISTINCT IV00102.LSTCNTDT FROM IV00102 WHERE (LOCNCODE = 'CENTRAL') AND (LSTCNTDT <> CONVERT(DATETIME, '1900-01-01 00:00:00', 102)))
LSTCNTDT
2016-04-27 00:00:00.000
2016-04-28 00:00:00.000
2016-04-29 00:00:00.000
2016-05-03 00:00:00.000
2016-05-04 00:00:00.000
2016-05-05 00:00:00.000
2016-05-06 00:00:00.000
2016-05-09 00:00:00.000
2016-05-10 00:00:00.000
2016-05-11 00:00:00.000
2016-05-13 00:00:00.000
2016-05-16 00:00:00.000
2016-05-17 00:00:00.000
2016-05-18 00:00:00.000
2016-05-19 00:00:00.000
2017-05-09 00:00:00.000
(SELECT DISTINCT IV00102.LSTCNTDT FROM IV00102 WHERE (LOCNCODE = 'CENTRAL') AND (LSTCNTDT <> CONVERT(DATETIME, '1900-01-01 00:00:00', 102)))
LSTCNTDT
2016-04-27 00:00:00.000
2016-04-28 00:00:00.000
2016-04-29 00:00:00.000
2016-05-03 00:00:00.000
2016-05-04 00:00:00.000
2016-05-05 00:00:00.000
2016-05-06 00:00:00.000
2016-05-09 00:00:00.000
2016-05-10 00:00:00.000
2016-05-11 00:00:00.000
2016-05-13 00:00:00.000
2016-05-16 00:00:00.000
2016-05-17 00:00:00.000
2016-05-18 00:00:00.000
2016-05-19 00:00:00.000
2017-05-09 00:00:00.000
Yeah you can't set the variable to an array of answers so you can only do one at a time. If you wanted to process all that in SQL you could use something like this (not tested as I don't actually have tables but this would iterate through each result and allow you to do the update).
SELECT DISTINCT ROW_NUMBER() OVER (ORDER BY LSTCNTDT) AS "ROW",IV00102.LSTCNTDT
INTO #temp
FROM IV00102
WHERE (LOCNCODE = 'CENTRAL') AND (LSTCNTDT <> CONVERT(DATETIME, '1900-01-01 00:00:00', 102))
DECLARE @x INT, @y INT
SET @x = 1
SET @y = (SELECT MAX(ROW) FROM #temp)
WHILE @x <= @y
BEGIN
DECLARE @nextDate datetime,@lstcntdt int
SET @lstcntdt = (SELECT LSTCNTDT FROM #temp WHERE ROW = @x)
SET @nextDate = (select dbo.getNextBusinessDay(@lstcntdt, 254))
--DO YOUR UPDATE QUERY HERE
SET @x = @x + 1
END
DROP TABLE #temp
ASKER
Dustin,
Ok, I will try your suggestion, is the function call based on your updated function or my original?
Ok, I will try your suggestion, is the function call based on your updated function or my original?
ASKER
also where you have the --DO YOUR UPDATE QUERY HERE what value would I pass to that query would i pass @nextDate
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks I will test it
ASKER
Thanks Dustin with a few mods that worked perfectly and did exactly what i wanted
Also, why not do the CONVERT(DATE, '2017-05-09', 102), 254 in the function so you don't have to type that in each time?