10

shiftPL/SQL 中是否有运算符的替代方案?有bitand函数,但它只接受binary_integer类型的参数。

如果我需要检查非常长的数字的低位/高位(可能在行中设置),我该怎么办?

C里面有和<<运营>>商。我如何在 PL/SQL 中实现它们?

4

3 回答 3

9

以下答案与字节序无关,我的措辞基于小端格式......

您可以简单地将参数乘以(左移)或除以(右移)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)
于 2009-06-30T19:53:50.703 回答
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。

于 2009-04-22T11:16:31.260 回答
3

这是我自己的 LPAD/RPAD 解决方案。

我以Tom Kyte 包为基础并对其进行扩展。

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> /
于 2009-04-22T11:56:11.383 回答