Both SQL-server and MySQL didn't cope with Recursive solvers. The flattened solver works, albeit a bit slow.
CREATE PROCEDURE `sudokuflat`(
IN `given` char(81)
)
labelBegin: begin
declare r0 int default 0;
declare c0 int default 0;/*can be negative*/
declare r1 int default 0;
declare c1 int default 0;
declare rb int default 0;
declare cb int default 0;
declare r2 int default 0;
declare c2 int default 0;
declare n int default 0;
declare nprev int default 0;/*convert from char*/
declare fnd int default 0;
declare fnd2 int default 0;
declare tmp char(81);
set tmp = given;
while r0 < 9 do
set c0 = 0;
while c0 < 9 do
if substr(tmp,r0*9+c0+1,1)='0' then
/*reset booleans TinyInt*/
set fnd2 = 0;
set n = 0;
/*set to last highest tested*/
if nprev <> 0 then
set n = nprev;
set nprev = 0;/*reset immediately*/
end if;
labelN: while n < 9 do
set n = n + 1;/*because of "continue" increase here*/
set fnd = 0;
/*checks*/
set r1 = 0;
labelA: while r1<9 do
if r0<>r1 and substr(tmp,r1*9+c0+1,1)=n then
set fnd = 1;
leave labelA;
end if;
set r1 = r1 + 1;
end while;
if fnd=1 and n<9 then
iterate labelN;
end if;
set c1 = 0;
labelB: while c1<9 do
if c0<>c1 and substr(tmp,r0*9+c1+1,1)=n then
set fnd = 1;
leave labelB;
end if;
set c1 = c1 + 1;
end while;
if fnd=1 and n<9 then
iterate labelN;
end if;
set rb = FLOOR(r0/3)*3;
set cb = FLOOR(c0/3)*3;
set r2 = rb;
labelC: while rb+3>r2 do
set c2 = cb;
while cb+3>c2 do
if (r0<>r2 or c0<>c2) and substr(tmp,r2*9+c2+1,1)=n then
set fnd = 1;
leave labelC;
end if;
set c2 = c2 + 1;
end while;
set r2 = r2 + 1;
end while;
if fnd=1 and n<9 then
iterate labelN;
end if;
/*try it*/
if fnd=1 then
leave labelN;/*n must be 9*/
end if;
set tmp = CONCAT(substr(tmp,1,r0*9+c0),n,substr(tmp,r0*9+c0+2,81));
set fnd2 = 1;
leave labelN;/*and continue*/
/*intelligent undo below; with recursion it was undone here*/
end while;
if fnd2=0 and fnd=1 and n=9 then
/*undo current position*/
set tmp = CONCAT(substr(tmp,1,r0*9+c0),'0',substr(tmp,r0*9+c0+2,81));
/*extra step back*/
if c0=0 then
set r0 = r0 - 1;
set c0 = 8; /*see below*/
else set c0 = c0 - 1;
end if;
while substr(given,r0*9+c0+1,1)<>'0' or substr(tmp,r0*9+c0+1,1)='9' do
/*if the last entered number was a 9, go even further back*/
if substr(given,r0*9+c0+1,1)='0' and substr(tmp,r0*9+c0+1,1)='9' then
set tmp = CONCAT(substr(tmp,1,r0*9+c0),'0',substr(tmp,r0*9+c0+2,81));
end if;
/*extra step back*/
if c0=0 then
set r0 = r0 - 1;
set c0 = 8; /*see below*/
else set c0 = c0 - 1;
end if;
end while;
set nprev = cast(substr(tmp,r0*9+c0+1,1) as unsigned);
/*undo backtrack also */
set tmp = CONCAT(substr(tmp,1,r0*9+c0),'0',substr(tmp,r0*9+c0+2,81));
set c0 = c0 - 1;/*contra below*/
end if;
end if;
set c0 = c0 + 1;/*this is meant by below*/
end while;
set r0 = r0 + 1;
end while;
if instr(tmp,'0')=0 then
INSERT INTO sudokutable(sudoku) VALUES(tmp);
end if;
end
SET @@SESSION.max_sp_recursion_depth = 255;
delete from sudokutable;
CALL `sudokuflat`('000000030050607004008903760000000520000216000042000000087302100200108090030000000');
select sudoku from sudokutable;
Takes about what feels like a minute... ;)