How to iterate over binary string in Oracle?

247 Views Asked by At

enter image description here

declare

str varchar2(2000) := :inputstr;
v_len number;
currChar CHAR(1);

begin
                v_len := length(str);
                for i in 1..v_len
                Loop
                        currChar  := substr(str,i,1);
                        if currChar = 1 then
              dbms_output.put_line('curr index' || i);
                        end if;
                End loop;
end;

When I pass '000111000' as input to IN_STRING variable , it trims the string and behaves very unusually.Please suggest some good approaches to iterate over binary strings like this.I am expecting output as 4,5,6 from above operation.

EDIT1: Please don't directly input the string as str varchar2(2000) := '000111000'; Instead input it from bind variable as I mentioned above.

2

There are 2 best solutions below

3
On BEST ANSWER

Your code works so long as you pass in a VARCHAR2 data type (and not a NUMBER).

You can also tidy up the code passing in the bind variable only once and using CONSTANTs to hold the values that are constant:

VARIABLE in_string VARCHAR2;

DECLARE
  c_string CONSTANT VARCHAR2(200) := :in_string;
  c_length CONSTANT PLS_INTEGER := LENGTH(c_string);
  v_out    CHAR(1);
BEGIN
  FOR i IN 1..c_length
  LOOP
    v_out := SUBSTR(c_string,i,1) ;
    DBMS_OUTPUT.PUT_LINE(v_out);
  END LOOP;
END;
/

Which outputs:

0
0
1
1
1
0
0
0

db<>fiddle here

2
On

Shouldn't behave unusual, unless datatype of in_string variable is NUMBER (then leading zeros don't have any meaning) - switch to VARCHAR2.

Illustration:

  1. NUMBER variable datatype
  2. value you enter
  3. result - really, missing leading zeros

enter image description here


Otherwise, it works OK (this is SQL*Plus so I used substitution variable):

SQL> DECLARE
  2     v_length  NUMBER (10);
  3     v_out     VARCHAR2 (20);
  4  BEGIN
  5     v_length := LENGTH ( '&&in_string');
  6
  7     FOR i IN 1 .. v_length
  8     LOOP
  9        v_out := SUBSTR ( '&&in_string', i, 1);
 10        DBMS_OUTPUT.PUT_LINE (v_out);
 11     END LOOP;
 12  END;
 13  /
Enter value for in_string: 00111000
0
0
1
1
1
0
0
0

PL/SQL procedure successfully completed.

Another option (if you're interested in it) doesn't require PL/SQL:

SQL>     SELECT SUBSTR ( '&&in_string', LEVEL, 1) val
  2        FROM DUAL
  3  CONNECT BY LEVEL <= LENGTH ( '&&in_string');

V
-
0
0
1
1
1
0
0
0

8 rows selected.

SQL>