Just for fun, I wanted to create a visual dice roller using SQL (I know that this is hardly what the language is designed for).
I've come up with the code below, which will roll as many dice as you like (@Dice
) and show a visual representation of each, like that of a normal six-sided die.
CREATE TABLE #Row1 ([1] CHAR(1), [2] CHAR(1), [3] CHAR(1))
CREATE TABLE #Row2 ([1] CHAR(1), [2] CHAR(1), [3] CHAR(1))
CREATE TABLE #Row3 ([1] CHAR(1), [2] CHAR(1), [3] CHAR(1))
DECLARE @Number INT
DECLARE @Count INT = 1
DECLARE @Dice INT = 2
WHILE @Count <= @Dice
BEGIN
SET @Number = ROUND(RAND(CONVERT(VARBINARY,NEWID()))*6,0,1)+1
INSERT INTO #Row1 ([1], [2], [3]) VALUES (
CASE WHEN @Number < 4 THEN ''
ELSE '•'
END
,''
,CASE WHEN @Number = 1 THEN ''
ELSE '•'
END
)
INSERT INTO #Row2 ([1], [2], [3]) VALUES (
CASE WHEN @Number <> 6 THEN ''
ELSE '•'
END
,CASE WHEN @Number % 2 = 0 THEN ''
ELSE '•'
END
,CASE WHEN @Number <> 6 THEN ''
ELSE '•'
END
)
INSERT INTO #Row3 ([1], [2], [3]) VALUES (
CASE WHEN @Number = 1 THEN ''
ELSE '•'
END
,''
,CASE WHEN @Number < 4 THEN ''
ELSE '•'
END
)
SELECT * FROM #Row1
UNION ALL
SELECT * FROM #Row2
UNION ALL
SELECT * FROM #Row3
TRUNCATE TABLE #Row1
TRUNCATE TABLE #Row2
TRUNCATE TABLE #Row3
SET @Count += 1
END
DROP TABLE #Row1
DROP TABLE #Row2
DROP TABLE #Row3
My question is, how could this be made more efficient? Is there a way to do this without so many UNION
s?
I'd also be interested in seeing any ideas people may have for expanding on this/making it more interesting!
Use a table variable instead of temporary tables. And include all three rows in the same table variable:
DECLARE @Rows TABLE ([Row] INT, [1] NCHAR(1), [2] NCHAR(1), [3] NCHAR(1));
DECLARE @Number INT;
DECLARE @Count INT = 1;
DECLARE @Dice INT = 2;
WHILE @Count <= @Dice
BEGIN
SET @Number = ROUND(RAND(CONVERT(VARBINARY,NEWID()))*6,0,1)+1;
INSERT INTO @Rows ([Row], [1], [2], [3]) VALUES
(
1
,CASE WHEN @Number < 4 THEN N'' ELSE N'•' END
,N''
,CASE WHEN @Number = 1 THEN N'' ELSE N'•' END
),
(
2
,CASE WHEN @Number <> 6 THEN N'' ELSE N'•' END
,CASE WHEN @Number % 2 = 0 THEN N'' ELSE N'•' END
,CASE WHEN @Number <> 6 THEN N'' ELSE N'•' END
),
(
3
,CASE WHEN @Number = 1 THEN N'' ELSE N'•' END
,N''
,CASE WHEN @Number < 4 THEN N'' ELSE N'•' END
);
SELECT [1], [2], [3] FROM @Rows ORDER BY [Row];
DELETE FROM @Rows;
SET @Count += 1;
END;
Edit:
I updated my solution, so that the three records are inserted in a single INSERT statement, instead of three separate INSERT statements for each record.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With