2009-04-22 57 views
7

在PL/SQL中是否有替代的shift運算符?有bitand函數,但它只接受binary_integer -type參數。PL/SQL中的移位運算符

如果我需要檢查真正長數的較低/較高位(可能設置在行中),該怎麼辦?

C<<>>運營商。我如何在PL/SQL中實現它們?

回答

3

這是我自己的LPAD/RPAD解決方案。

我把Tom Kyte package作爲基礎,並擴大它。

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

而且測試

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

由於Oracle版本8可能會在數據庫中使用java代碼。在PL/SQL中,您可以爲java代碼定義一個包裝器。例如

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; 

在java代碼中,您可以使用shift運算符。雖然有點笨拙,但它可以這樣工作。

不幸的是,對於Oracle XE來說這是不可能的,因爲在'免費'版中不支持Java。

+0

很好的解決方案,謝謝。 我找到pl/sql的方式,我會在幾分鐘之內發佈 – drnk 2009-04-22 11:36:23

6

以下的答案是不是字節序無關,我的措辭是基於小端格式...

您可以按住Shift位乘以簡單(移左移)或將參數除以2(右移)x的冪,其中x是要移位的位數。例如,如果我需要低階字節移位的數字(255:11111111)的16位到我將執行以下操作中的左:

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

相反地,如果我想轉移的值16711680我會執行以下16位:

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