2009-04-22 10 views
7

Gibt es eine Alternative von shift Operatoren in PL/SQL? Es gibt bitand Funktion, aber es akzeptiert nur binary_integer-Typ Argumente.Schichtoperatoren in PL/SQL

Was soll ich tun, wenn ich ein niedrigeres/höheres Bit mit wirklich langer Nummer (wahrscheinlich in der Zeile) überprüfen muss?

In C gibt es << und >> Operatoren. Wie kann ich sie in PL/SQL realisieren?

Antwort

3

Hier ist meine eigene LPAD/RPAD-Lösung.

Ich nehme Tom Kyte package als Basis und erweitern Sie es.

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; 
/

und 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

Seit Oracle Version 8 ist es möglich, Java-Code in der Datenbank zu verwenden. In PL/SQL können Sie einen Wrapper für den Java-Code definieren. z.B.

Im Java-Code können Sie dann den Schichtoperator verwenden. Obwohl ein bisschen ungeschickt, aber es kann so funktionieren.

Leider ist dies mit Oracle XE nicht möglich, da Java in dieser "kostenlosen" Version nicht unterstützt wird.

+0

nette Lösung, danke. ich finde pl/sql weg, dass ich innerhalb weniger minuten posten soll – drnk

6

Die folgende Antwort wird auf Little-Endian-Format nicht endianness Agnostiker und meine Formulierung basiert ...

Sie können einfach verschieben Bits multipliziert (shift links) oder dividieren (rechts verschieben) das Argument um 2 zur Potenz von x, wobei x die Anzahl der zu verschiebenden Bits ist. Zum Beispiel, wenn ich brauche die niederwertige Byte einer Reihe (255: 11111111) zu verschieben, 16 Bits nach links I die folgenden Operation durchführen würde:

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

Umgekehrt, wenn I den Wert 16.711.680 verschieben will 16 Bits nach rechts würde ich folgendes durchführen:

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