AND CAST(SUBSTRING(CONVERT(VARCHAR(10),h.run_date) , 5,2) +'-'
+ SUBSTRING(CONVERT(VARCHAR(10),h.run_date) , 7,2) +'-'
+ SUBSTRING(CONVERT(VARCHAR(10),h.run_date),1,4) AS SMALLDATETIME) = CONVERT(VARCHAR(10), GETDATE(), 121)
is destined to scan the entire sysjobhistory table.
For small sysjobhistory row counts, that scan may be acceptable. For large sysjobhistory row counts, the same scan can result in unacceptable blocking. To avoid the scan, it might be useful to create an index upon sysjobhistory(run_date). But, the index would need to be checked (verified to be in place and functional) after each msdb upgrade. To harness seeking, the above clause would also be rewritten, so that all scalar operations are solely accomplished upon GETDATE(), and never accomplished upon a column (such as h.run_date, as done in above clause), with the run_date clause instead being BETWEEN two such scalar operations.
For similar upgrade reasons (this time concerning upgrades of master, not msdb), a reliance upon master.dbo.spt_values might be risky. Its DDL and purpose are not documented, which means Microsoft can change its DDL or its contents (whenever Microsoft see fit, without any advanced public notice). It thus may be more robust to create a [Numbers] table and to reference it (instead of master.dbo.spt_values).