Regular Sudoku solver in SQL Server

Both SQL-server and MySQL didn't cope with Recursive solvers. The flattened solver works, albeit a bit slow.

Stored Procedure


CREATE PROCEDURE [sudokuflat](
	@given Char(81)
)
as
begin
declare @r0    int = 0;
declare @c0    int = 0;/*can be negative*/
declare @r1    int = 0;
declare @c1    int = 0;
declare @rb    int = 0;
declare @cb    int = 0;
declare @r2    int = 0;
declare @c2    int = 0;
declare @n     int = 0;
declare @nprev int = 0;/*convert from char*/
declare @fnd   int = 0;
declare @fnd2  int = 0;
declare @tmp   Char(81) = @given;

	while @r0 < 9 
	begin
		set @c0 = 0;
		while @c0 < 9 
		begin
			if substring(@tmp,@r0*9+@c0+1,1)='0' 
			begin
				/*reset booleans TinyInt*/
				set @fnd2 = 0;
				set @n = 0;
				/*set to last highest tested*/
				if @nprev <> 0 
				begin
					set @n = @nprev;
					set @nprev = 0;/*reset immediately*/
				end
				labelN: while @n < 9 
				begin
					set @n = @n + 1;/*because of "continue" increase here*/
					set @fnd = 0;
					/*checks*/
					set @r1 = 0;
					while @r1<9 
					begin
						if @r0<>@r1 and substring(@tmp,@r1*9+@c0+1,1)=@n 
						begin
							set @fnd = 1;
							break;
						end
						set @r1 = @r1 + 1;
					end
					if @fnd=1 and @n<9 
					begin 
						continue;
					end
					set @c1 = 0;
					while @c1<9 
					begin
						if @c0<>@c1 and substring(@tmp,@r0*9+@c1+1,1)=@n 
						begin
							set @fnd = 1;
							break;
						end
						set @c1 = @c1 + 1;
					end
					if @fnd=1 and @n<9 
					begin 
						continue;
					end
					set @rb = FLOOR(@r0/3)*3;
					set @cb = FLOOR(@c0/3)*3;
					set @r2 = @rb;
					while @r2<@rb+3 begin
						set @c2 = @cb;
						while @c2<@cb+3 begin
							if (@r0<>@r2 or @c0<>@c2) and substring(@tmp,@r2*9+@c2+1,1)=@n 
							begin
								set @fnd = 1;
								break;
							end
							if @fnd = 1 break;
							set @c2 = @c2 + 1;
						end
						set @r2 = @r2 + 1;
					end
					if @fnd=1 and @n<9 
					begin
						continue;
					end
					/*try it*/
					if @fnd=1 
					begin 
						break;/*n must be 9*/
					end
					
					set @tmp = CONCAT(substring(@tmp,1,@r0*9+@c0),@n,substring(@tmp,@r0*9+@c0+2,81));
					set @fnd2 = 1;
					break;/*and continue*/
					/*intelligent undo below; with recursion it was undone here*/
				end
				if @fnd2=0 and @fnd=1 and @n=9 
				begin
					/*undo current position*/
					set @tmp = CONCAT(substring(@tmp,1,@r0*9+@c0),'0',substring(@tmp,@r0*9+@c0+2,81));
					/*extra step back*/
					if @c0=0 
					begin
						set @r0 = @r0 - 1;
						set @c0 = 8; /*see below*/
					end
					else 
					begin
						set @c0 = @c0 - 1;
					end
					while substring(@given,@r0*9+@c0+1,1)<>'0' or substring(@tmp,@r0*9+@c0+1,1)='9' 
					begin
						/*if the last entered number was a 9, go even further back*/
						if substring(@given,@r0*9+@c0+1,1)='0' and substring(@tmp,@r0*9+@c0+1,1)='9' 
						begin 
							set @tmp = CONCAT(substring(@tmp,1,@r0*9+@c0),'0',substring(@tmp,@r0*9+@c0+2,81));
						end
						/*extra step back*/
						if @c0=0 
						begin
							set @r0 = @r0 - 1;
							set @c0 = 8; /*see below*/
						end
						else 
						begin
							set @c0 = @c0 - 1;
						end
					end
					set @nprev = cast(substring(@tmp,@r0*9+@c0+1,1) as int);
					/*undo backtrack also */
					set @tmp = CONCAT(substring(@tmp,1,@r0*9+@c0),'0',substring(@tmp,@r0*9+@c0+2,81));
					set @c0 = @c0 - 1;/*contra below*/
				end
			end
			set @c0 = @c0 + 1;/*this is meant by below*/
		end
		set @r0 = @r0 + 1;
	end
	if charindex('0',@tmp)=0 
	begin
		INSERT INTO sudokutable(sudoku) VALUES(@tmp);
	end
end

Usage


DELETE FROM [sudokutable]

GO

DECLARE	@return_value int

EXEC	@return_value = [dbo].[sudokuflat]
		@given = N'000000030050607004008903760000000520000216000042000000087302100200108090030000000'

SELECT TOP 1000 [sudoku] FROM [sudokutable]

GO

Takes a few seconds...