2009-04-22 32 views
7

Liệu có một sự thay thế của các toán tử shift trong PL/SQL không? Có chức năng bitand nhưng chỉ chấp nhận các đối số loại binary_integer.Các toán tử dịch chuyển trong PL/SQL

Tôi nên làm gì nếu tôi cần kiểm tra bit thấp hơn/cao hơn của số thực sự dài (có thể được đặt trong dòng)?

Trong C có các toán tử <<>>. Làm thế nào tôi có thể nhận ra chúng trong PL/SQL?

Trả lời

3

Đây là giải pháp LPAD/RPAD của riêng tôi.

Tôi lấy Tom Kyte package làm cơ sở và mở rộng.

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

Và kiểm tra

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

Vì phiên bản Oracle 8 có thể bạn sử dụng mã java trong cơ sở dữ liệu. Trong PL/SQL, bạn có thể định nghĩa một trình bao bọc cho mã java. ví dụ.

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; 

Trong mã java, bạn có thể sử dụng toán tử shift. Mặc dù hơi vụng về, nhưng nó có thể hoạt động theo cách này.

Đáng buồn thay, điều này là không thể với Oracle XE, vì không có hỗ trợ cho Java trong phiên bản 'miễn phí' đó.

+0

giải pháp tốt, cảm ơn. tôi tìm cách pl/sql, tôi sẽ đăng trong vòng vài phút – drnk

6

Câu trả lời sau đây được không endianness thuyết bất khả tri và cách diễn đạt của tôi là dựa trên định dạng về cuối nhỏ chút ...

Bạn có thể thay đổi bit đơn giản nhân (shift bên trái) hoặc phân chia (dịch chuyển phải) đối số bằng 2 với lũy thừa của x trong đó x là số bit cần dịch chuyển. ví dụ, nếu tôi cần phải thay đổi byte ở vị trí thấp của một số (255: 11111111) 16 bit bên trái tôi sẽ thực hiện các hoạt động sau:

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

ngược lại, nếu tôi muốn thay đổi giá trị 16.711.680 16 bit ở bên phải tôi sẽ thực hiện như sau:

select 16711680/power(2,16) from dual; 
-- the result will be (255:11111111) 
Các vấn đề liên quan