I am wanting to have a script which updates a table of days, setting the bankHoliday flag to true if it exists in a given list.
This list is something a user would update every year or two:
DECLARE @dateList VARCHAR(MAX) = '2024-01-01, 2024-03-29, 2024-04-01, 2024-05-06, 2024-05-27,
2024-08-26, 2024-12-25, 2024-12-26, 2025-01-01,
2025-04-18, 2025-04-21, 2025-05-05, 2025-05-26,
2025-08-25, 2025-12-25, 2025-12-26';
The update happens at the bottom of a long script, so though I can tell the user at the top something like "--make sure to go to ~line 300 and update the list of bank holidays", I would prefer to have this list at the top in a variable and then refer to it down in the update.
The first problem I have is for it to be easily visible, it can be on multiple lines and have spaces, like the above example. So I have this bit of code following it to strip out all the wrong characters:
-- Replace the dashes with single quotes
SET @dateList = REPLACE(@dateList, ',', ''',''');
-- Replace multiple spaces and new lines with a single space
SET @dateList = REPLACE(REPLACE(@dateList, CHAR(13) + CHAR(10), ' '), ' ', '');
-- Add single quotes at the beginning and end
SET @dateList = '''' + @dateList + '''';
Doing select @dateList at this point returns this:
'2024-01-01','2024-03-29','2024-04-01','2024-05-06','2024-05-27','2024-08-26','2024-12-25','2024-12-26','2025-01-01','2025-04-18','2025-04-21','2025-05-05','2025-05-26','2025-08-25','2025-12-25','2025-12-26'
So now, down at the bottom of the script, i want to use @dateList in my update:
I tried the following, but each time get the same error: Conversion failed when converting date and/or time from character string.
UPDATE days
SET days.PublicHoliday = 1
WHERE days.Date IN
(
SELECT value FROM STRING_SPLIT(@dateList, ',')
);
UPDATE days
SET days.PublicHoliday = 1
WHERE days.Date IN
(
@dateList
);
UPDATE days
SET days.PublicHoliday = 1
WHERE days.Date IN
(
SELECT CONVERT(datetime, value) FROM STRING_SPLIT(@dateList, ',')
);
Again, if i put the result of @dateList directly into the update, it works fine:
UPDATE days
SET days.PublicHoliday = 1
WHERE days.Date IN
(
'2024-01-01','2024-03-29','2024-04-01','2024-05-06','2024-05-27','2024-08-26','2024-12-25','2024-12-26','2025-01-01','2025-04-18','2025-04-21','2025-05-05','2025-05-26','2025-08-25','2025-12-25','2025-12-26'
);
but i want to avoid this if possible as it requires trusting the user to go to the foot of the script.
IN (@dateList)doesn't do what you think it does; it would be equivalent to= @dateListYou can't just dump a scalar variable into anINand expect SQL Server to treat is like a tuple. Use a table type variable/parameter or temporary table.yyyy-MM-ddis not unambigious with thedatetimedatatype. What happens with yourSTRING_SPLITsolution if you use an unambiguous format (yyyyMMdd)?,means that all values except one will have a leading space character, eg' 2023-01-01'instead of'2023-01-01'. The safe option is to use a table-valued parameter ofdatevalues. Another option is to use a JSON array with aWITHclause that defines the values as dates, egselect MyDate from openjson('["2023-12-31","2022-02-02"]') with (MyDate date '$')