2009-04-22 40 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)