Something like this (untested)
;WITH cNumbers AS
(
SELECT
ROW_NUMBER() OVER (ORDER BY c1.object_id) AS ArbitraryNumber
FROM
sys.columns c1 CROSS JOIN sys.columns c2
)
SELECT
M.ID, N.ArbritraryNumber
FROM
MyTable M
JOIN
cNumbers N ON N.ArbitraryNumber BETWEEN M.Start AND M.End
Edit:
The cross join gives 298,116 rows in my tempdb. And 1,865,956 in a user DB.
If nearly 300k isn't enough, add another CROSS JOIN.
This gives me 162,771,336 in tempdb and 2,548,895,896 in a user DB:
SELECT
COUNT_BIG(*) --note bigint
FROM
sys.columns c1 CROSS JOIN sys.columns c2 CROSS JOIN sys.columns c3