conversione esadecimale - decimale e
formato COMP-3 (cobol)


sorgente PL/SQL
commento al sorgente
risultato
commento al risultato

L'esempio seguente è abbastanza complesso da meritare anche una limitata analisi del codice PL/SQL:



create or replace function fn_hex2dec (ix varchar2 ) return number is

  l   smallint;
  ris number;
  f   number;
  x   varchar2(40);

function hdec (x char ) return smallint is
  y smallint;
begin
  if x in ('0','1','2','3','4','5','6','7','8','9')  then
      y:= x;
  elsif x in('a','b','c','d','e','f') then
      y:= ascii(x) -87;
  else
      y:= null;
  end if;

  return y;
end;

begin
  x:=lower(ix);
  l:=  length(x) ;
  f:= 1;
  ris :=0;
  while l>0 loop
     ris := ris + hdec(substr(x,l,1))*f;
     f:=f*16;
     l:=l-1;
  end loop;
  return ris;
end;
/



create or replace function fn_comp3(x number , ncifre smallint, autoconv char default 's') return varchar2 is
  y    varchar2(30);
  xs   varchar2(30);
  s    varchar2(30);
  l    smallint;
  ndec smallint;
  segno char;
  xcifre smallint :=ncifre;

begin
  if xcifre mod 2 =0 then
     xcifre := xcifre+1;
  end if;

  xs := ltrim(to_char( nvl(x,0) , rpad('0',xcifre,'9'))) ;

  ----- nel caso di numeri che non rientrano nel numero di cifre specificato, xs risulta '##..##' , la fn_hex2dec ritorna quindi null e la
  ----- fn_trasc ('da-mvs') segnala l'errore

  l:= length(xs) ;
  if x<0 then segno :='D';
  else        segno :='C';
  end if;

  while l>0 loop
      s:= substr (xs,l);
      xs:= substr (xs,1,l-1);
      if length(s)=1 then
          s:=s|| segno ;
      end if;

      ndec:=fn_hex2dec (s) ;
      if ndec = 0 then
         ndec :=204;   ------- necessario * probl con chr(0) = fine stringa
      end if;

      y := chr(ndec ) || y ;
      l:=l-2;
  end loop;

  if autoconv='s' then
       y:= fn_trasc(y, 'da-mvs');
  end if;

  return y;
  --------- y := hextoraw( x||'C');  ma non funziona..

end;

/




select * from tabella1
/







Queste 2 funzioni provengono da un "caso reale" e mostrano già alcune caratteristiche importanti dello sviluppo in PL/SQL;
la prima funzione (fn_hex2dec) viene utilizzata dalla seconda: (lo si può verificare con una select * from user_dependencies);

la fn_hex2dec converte un valore esadecimale (passato come varchar2) nel decimale corrispondente;

la fn_comp3 invece converte un valore decimale (integer) nella rappresentazione COMP-3 corrispondente; lo stesso risultato dovrebbe essere ottenibile usando la funzione predefinita Oracle hextoraw, ma quando si cerca di scrivere l'output di tale funzione su un file (usando il package utl_file) si ottengono risultati errati;




risultato:

create or replace function fn_hex2dec (ix varchar2 ) return number is l sma...




errori:



NAMETYPESEQUENCELINEPOSITIONTEXT
PROVA2PROCEDURE1.3.24.PLS-00103: Encountered the symbol "2" when expecting one of the following: ( select <an identifier> <a double-quoted delimited-identifier>



create or replace function fn_comp3(x number , ncifre smallint, autoconv...




errori:



NAMETYPESEQUENCELINEPOSITIONTEXT
FN_COMP3FUNCTION1.23.1.PLS-00103: Encountered the symbol "" when expecting one of the following: begin declare end exception exit for goto if loop mod null pragma raise return select update while <an identifier> <a double-quoted delimited-identifier> <a bind variable> <a single-quoted SQL string> << close delete fetch lock insert open rollback savepoint set sql commit The symbol "" was ignored.
FN_COMP3FUNCTION2.24.19.PLS-00103: Encountered the symbol "" when expecting one of the following: begin declare end exception exit for goto if loop mod null pragma raise return select update while <an identifier> <a double-quoted delimited-identifier> <a bind variable> <a single-quoted SQL string> << close delete fetch lock insert open rollback savepoint set sql commit The symbol "" was ignored.
FN_COMP3FUNCTION3.25.27.PLS-00103: Encountered the symbol "" when expecting one of the following: begin declare else elsif end exit for goto if loop mod null pragma raise return select update while <an identifier> <a double-quoted delimited-identifier> <a bind variable> <a single-quoted SQL string> << close delete fetch lock insert open rollback savepoint set sql commit The symbol "" was ignored.
FN_COMP3FUNCTION4.26.27.PLS-00103: Encountered the symbol "" when expecting one of the following: begin declare end exit for goto if loop mod null pragma raise return select update while <an identifier> <a double-quoted delimited-identifier> <a bind variable> <a single-quoted SQL string> << close delete fetch lock insert open rollback savepoint set sql commit
PROVA2PROCEDURE1.3.24.PLS-00103: Encountered the symbol "2" when expecting one of the following: ( select <an identifier> <a double-quoted delimited-identifier>



select * from tabella1

COL1COL2
72001-03-26 11:43:34
72001-03-26 11:45:03
72001-03-26 11:57:12
72001-03-26 12:04:09
72001-03-27 14:14:09
72001-03-27 14:23:27
72001-03-27 14:44:15
72001-03-27 15:30:49
22001-03-29 11:02:39
22001-03-29 11:03:35
22001-03-29 11:03:55
22001-03-29 11:32:10
22001-03-29 11:35:58
32001-03-29 11:38:11





La prima cosa da tenere presente nel leggere gli errori sopra riportati è che tutti gli esempi proposti sono "cumulativi" e rappresentano la situazione reale del database nel momento in cui sono stati eseguiti:

il primo errore si riferisce alla procedura prova2 creata precedentemente nell'esempio 4 (avitare di mostrarlo potrebbe essere un primo miglioramento..);

gli errori successivi si riferiscono alla fn_comp3,che utilizza una funzione non precedentemente definite (fn_trasc);
è da notare però che in questo caso gli errori riportati sono dovuti alle 2 lunghe righe di commento, che non vengono interpretati correttamente (questo è probabilmente un bug, ci sto lavorando..:-! v.nota );