Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a visual dice roller with T-SQL (just for fun)

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 UNIONs?

I'd also be interested in seeing any ideas people may have for expanding on this/making it more interesting!

like image 481
Simmo33 Avatar asked Apr 12 '19 12:04

Simmo33


1 Answers

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.

like image 135
Bart Hofland Avatar answered Oct 30 '22 15:10

Bart Hofland