2009-04-22 7 views
7

Existe-t-il une alternative aux opérateurs shift en PL/SQL? Il y a fonction, mais il accepte seulement binary_integer -type arguments.Opérateurs de décalage dans PL/SQL

Que dois-je faire si j'ai besoin de vérifier un bit inférieur/supérieur de très grand nombre (probablement défini dans la ligne)?

En C il y a << et >> opérateurs. Comment je peux les réaliser en PL/SQL?

Répondre

3

Voici ma propre solution LPAD/RPAD.

Je prends Tom Kyte package comme base et je l'agrandis.

create or replace function bin_shift_right 
( p_bin in varchar2, 
    p_shift in number default null) return varchar2 
is 
    l_len number; 
    l_shift number; 
begin 
    l_shift := nvl(p_shift, 1); 
    l_len := length(p_bin); 
    if (l_len <= 0) then 
     return null; 
    end if; 
    if (l_shift > l_len) then 
     l_shift := l_len; 
    end if; 

    return lpad(substr(p_bin, 1, l_len - l_shift), l_len, '0'); 
end bin_shift_right; 

create or replace function shright 
( p_num in number, 
    p_shift in number default null) return number 
is 
begin 
    if (trunc(p_num) <> p_num OR p_num < 0) then 
     raise PROGRAM_ERROR; 
    end if; 
    return nvl(to_dec(bin_shift_right(to_bin(p_num), p_shift), 2), 0); 
end shright; 
/

et des tests

SQL> 
SQL> select shright(123) from dual; 

SHRIGHT(123) 
------------ 
      61 

SQL> 
SQL> select shright(123, 2) from dual; 

SHRIGHT(123,2) 
-------------- 
      30 

SQL> 
SQL> select shright(123, 10) from dual; 

SHRIGHT(123,10) 
--------------- 


SQL>/
5

Depuis Oracle version 8, il est possible que vous utilisiez du code Java dans la base de données. En PL/SQL, vous pouvez définir un wrapper pour le code Java. par exemple.

PACKAGE BODY JAVA_CODE 
IS 
    function bitshift_left(x in number, 
         n in number) return number 
    is language java name 'com.foo.Bitshift(java.lang.Integer, 
              java.lang.Integer) return java.lang.Integer'; 
END JAVA_CODE; 

Dans le code Java, vous pouvez utiliser l'opérateur de décalage. Bien qu'un peu maladroit, mais cela peut fonctionner de cette façon. Malheureusement, cela n'est pas possible avec Oracle XE, car il n'y a pas de support pour Java dans cette édition «gratuite».

+0

belle solution, merci. je trouve pl/sql way, que je posterai dans quelques minutes – drnk

6

La réponse suivante est boutisme pas agnostique et mon libellé est basé sur petit format endian ...

Vous pouvez déplacer les bits simple multiplication (décalage à gauche) ou en divisant (shift right) l'argument par 2 à la puissance de x où x est le nombre de bits à décaler. par exemple, si je dois changer l'octet de poids faible d'un certain nombre (255: 11111111) 16 bits à gauche j'effectuer l'opération suivante:

select 255 * power(2,16) from dual; 
-- the result will be (16711680:111111110000000000000000) 

à l'inverse, si je veux changer la valeur 16711680 16 bits vers la droite, je voudrais effectuer ce qui suit: