Regular Sudoku solver in PL/SQL

Below is a non recursive sudoku solver in PL/SQL, converted from MySQL version.

Stored Procedure


CREATE OR REPLACE PROCEDURE sudokuflat(
	given in varchar2
)
is
    r0    int := 0;
    c0    int := 0;/*can be negative*/
    r1    int := 0;
    c1    int := 0;
    rb    int := 0;
    cb    int := 0;
    r2    int := 0;
    c2    int := 0;
    n     int := 0;
    nprev int := 0;/*convert from char*/
    fnd   int := 0;
    fnd2  int := 0;
    tmp   varchar2(81) := given;
begin
	while r0 < 9 
	loop
		c0 := 0;
		while c0 < 9 
		loop
			if substr(tmp,r0*9+c0+1,1)='0' then
				/*reset booleans TinyInt*/
				fnd2 := 0;
				n := 0;
				/*set to last highest tested*/
				if nprev <> 0 then
					n := nprev;
					nprev := 0;/*reset immediately*/
				end if;
				<> 
				while n < 9 
				loop
					n := n + 1;/*because of "continue" increase here*/
					fnd := 0;
					/*checks*/
					r1 := 0;
					<> 
					while r1<9 
					loop
						if r0<>r1 and substr(tmp,r1*9+c0+1,1)=n then
							fnd := 1;
							exit labelA;
						end if;
						r1 := r1 + 1;
					end loop;
					if fnd=1 and n<9 then 
						continue;
					end if;
					c1 := 0;
					<>
					while c1<9 
					loop
						if c0<>c1 and substr(tmp,r0*9+c1+1,1)=n then
							fnd := 1;
							exit labelB;
						end if;
						c1 := c1 + 1;
					end loop;
					if fnd=1 and n<9 then 
						continue;
					end if;
					rb := FLOOR(r0/3)*3;
					cb := FLOOR(c0/3)*3;
					r2 := rb;
					<> 
					while rb+3>r2 
					loop
						c2 := cb;
						while cb+3>c2 
						loop
							if (r0<>r2 or c0<>c2) and substr(tmp,r2*9+c2+1,1)=n then
								fnd := 1;
								exit labelC;
							end if;
							c2 := c2 + 1;
						end loop;
						r2 := r2 + 1;
					end loop;
					if fnd=1 and n<9 then
						continue;
					end if;
					/*try it*/
					if fnd=1 then 
						exit labelN;/*n must be 9*/
					end if;
					
					tmp := substr(tmp,1,r0*9+c0)||n||substr(tmp,r0*9+c0+2,81);
					fnd2 := 1;
					exit labelN;/*and continue*/
					/*intelligent undo below; with recursion it was undone here*/
				end loop;
				if fnd2=0 and fnd=1 and n=9 then
					/*undo current position*/
					tmp := substr(tmp,1,r0*9+c0)||'0'||substr(tmp,r0*9+c0+2,81);
					/*extra step back*/
					if c0=0 then
						r0 := r0 - 1;
						c0 := 8; /*see below*/
					else c0 := c0 - 1;
					end if;
					while substr(given,r0*9+c0+1,1)<>'0' or substr(tmp,r0*9+c0+1,1)='9' 
					loop
						/*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 
							tmp := substr(tmp,1,r0*9+c0)||'0'||substr(tmp,r0*9+c0+2,81);
						end if;
						/*extra step back*/
						if c0=0 then
							r0 := r0 - 1;
							c0 := 8; /*see below*/
						else c0 := c0 - 1;
						end if;
					end loop;
					nprev := cast(substr(tmp,r0*9+c0+1,1) as int);
					/*undo backtrack also */
					tmp := substr(tmp,1,r0*9+c0)||'0'||substr(tmp,r0*9+c0+2,81);
					c0 := c0 - 1;/*contra below*/
				end if;
			end if;
			c0 := c0 + 1;/*this is meant by below*/
		end loop;
		r0 := r0 + 1;
	end loop;
	if instr(tmp,'0')=0 then
		dbms_output.put_line(tmp);
	end if;
end;
/

SHOW ERRORS

set linesize 100

begin
	sudokuflat('000000030050607004008903760000000520000216000042000000087302100200108090030000000');
end;
/

PL/SQL playground