Listing 4: Creating the fn_sudoku Function IF OBJECT_ID('dbo.fn_sudoku') IS NOT NULL DROP FUNCTION dbo.fn_sudoku; GO CREATE FUNCTION dbo.fn_sudoku() RETURNS @Sudoku TABLE ( row INT NOT NULL, col INT NOT NULL, val INT NOT NULL, PRIMARY KEY(row, col, val) ) AS BEGIN DECLARE @rc AS INT; DECLARE @SudokuUnique TABLE ( row INT NOT NULL, col INT NOT NULL, box INT NOT NULL, val INT NOT NULL, PRIMARY KEY(row, col), UNIQUE(row, val), UNIQUE(col, val), UNIQUE(box, val) ); DECLARE @SudokuNonUnique TABLE ( row INT NOT NULL, col INT NOT NULL, box INT NOT NULL, val INT NOT NULL, PRIMARY KEY(row, col, val) ); -- BEGIN CALLOUT A INSERT INTO @SudokuUnique(row, col, val, box) SELECT row, col, val, (row-1)/3*3 + (col-1)/3 + 1 FROM SudokuInput; -- END CALLOUT A -- BEGIN CALLOUT B INSERT INTO @SudokuNonUnique(row, col, val, box) SELECT R.n AS row, C.n AS col, V.n, (R.n-1)/3*3 + (C.n-1)/3 + 1 FROM Nums AS R, Nums AS C, Nums AS V WHERE R.n <= 9 AND C.n <= 9 AND V.n <= 9 AND NOT EXISTS (SELECT * FROM SudokuInput AS S WHERE S.row = R.n AND S.col = C.n); -- END CALLOUT B SET @rc = @@rowcount; -- BEGIN CALLOUT C WHILE @rc > 0 BEGIN SET @rc =0; -- Rules that remove nonfinal values FROM @SudokuNonUnique -- Rules that load final values into @SudokuUnique -- After each insert/delete, SET @rc = @rc + @@rowcount END -- END CALLOUT C INSERT INTO @Sudoku(row, col, val) SELECT row, col, val FROM @SudokuUnique UNION ALL SELECT row, col, val FROM @SudokuNonUnique RETURN; END