/**rowid長度為18位﹐64進制來表示﹕****
對像編號(6位) + 文件編號(3位) + 塊號(6位) + 行號(3位)
A-Z 0 - 25
a-z 26 - 51
0-9 52 - 61
+ 62
/ 63
**********/
v_row VARCHAR2(64):='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
v_flag VARCHAR2(1);
FUNCTION f_jx(dd IN VARCHAR2) RETURN NUMBER IS
v_slen NUMBER; --字串長度
v_num NUMBER; --計算結果
v_pos NUMBER; --所在位置﹐即所代表10進制數﹐當然要減1
BEGIN
v_slen :=LENGTH(dd);
v_num:=0;
FOR i IN 1..v_slen LOOP
v_pos :=INSTR(v_row,SUBSTR(dd,i,1)) -1;
v_num :=v_num+v_pos*POWER(64,(v_slen-i));
END LOOP;
RETURN v_num;
END f_jx;
BEGIN
v_flag :='Y';
IF LENGTH(rid)=18 THEN
FOR i IN 1..18 LOOP
IF INSTR(v_row,SUBSTR(rid,i,1))<=0 THEN
v_flag :='N';
END IF;
END LOOP;
ELSE
v_flag :='N';
END IF;
IF v_flag='Y' THEN
DBMS_OUTPUT.PUT_LINE('DATA_OBJECT_ID:= '|| F_JX(SUBSTR(rid,1,6)));
DBMS_OUTPUT.PUT_LINE('RELATIVE_FILE_NUMBER:= '|| F_JX(SUBSTR(rid,7,3)));
DBMS_OUTPUT.PUT_LINE('BLOCK_NUMBER:= ' || F_JX(SUBSTR(rid,10,6)));
DBMS_OUTPUT.PUT_LINE('ROW_NUMBER:= ' || F_JX(SUBSTR(rid,16,3)));
ELSE
DBMS_OUTPUT.PUT_LINE('傳入格式不符何rowid');
END IF;
END p_rowid;
v_rowid_type int;
v_object_number number;
v_relative_fno int;
v_block_number number;
v_row_number int;
BEGIN
dbms_rowid.rowid_info(dd,v_rowid_type,v_object_number,v_relative_fno,v_block_number,v_row_number);
dbms_output.put_line('ROWID_TYPE:'||v_rowid_type||' '||'備注﹕1表示rowid是extended,0表示rowid是restrictedv_rowid_type');
dbms_output.put_line('DATA_OBJECT_ID:'||v_object_number );
dbms_output.put_line('RELATIVE_FNO:'||v_relative_fno );
dbms_output.put_line('BLOCK_NUMBER:'||v_block_number );
dbms_output.put_line('ROW_NUMBER:'||v_row_number );
END P_ROWID2;
实际上就是将十进制数转化成64进制数,当然,从二进制转化的规则比较简单点。
将二进制数从右到左,6个bit一组,然后将这6个bit组转成10进制数,就是A~Z a~z 0~9 + /这64个字符的位置(从0开始),替换成base64的字符即可。
DATA_OBJECT_ID:= 97795
RELATIVE_FILE_NUMBER:= 4
BLOCK_NUMBER:= 4181
ROW_NUMBER:= 0
CREATE OR REPLACE FUNCTION NUMBER_2_BIT(V_NUM NUMBER) RETURN VARCHAR IS
V_RTN VARCHAR(2000);
V_N1 NUMBER;
V_N2 NUMBER;
BEGIN
V_N1 := ABS(V_NUM);
--如果为正数
IF SIGN(V_NUM) > 0 THEN
LOOP
V_N2 := MOD(V_N1, 2);
V_N1 := ABS(TRUNC(V_N1 / 2));
V_RTN := TO_CHAR(V_N2) || V_RTN;
EXIT WHEN V_N1 = 0;
END LOOP;
--dbms_output.put_line('正数结果'||V_RTN);
--补全32位高位0
SELECT lpad(V_RTN,32,0)
INTO V_RTN
FROM dual;
--dbms_output.put_line('正数补全结果'||V_RTN);
ELSE
--转换为二进制同时按位取反
LOOP
V_N2 := MOD(V_N1, 2);
IF V_N2 = 1 THEN
V_N2 := 0;
ELSIF V_N2 = 0 THEN
V_N2 := 1;
END IF;
V_N1 := ABS(TRUNC(V_N1 / 2));
V_RTN := TO_CHAR(V_N2) || V_RTN;
EXIT WHEN V_N1 = 0;
END LOOP;
--dbms_output.put_line('负数结果'||V_RTN);
--补全32位高位1
SELECT lpad(V_RTN,32,1)
INTO V_RTN
FROM dual;
--dbms_output.put_line('负数补全1结果'||V_RTN);
--二进制转换为10机制,同时+1
SELECT SUM(data1) + 1
INTO V_N1
FROM (SELECT substr(V_RTN, rownum, 1) * power(2, length(V_RTN) - rownum) data1
FROM dual
CONNECT BY rownum <= length(V_RTN));
-- dbms_output.put_line('转换为十进制数结果'||V_RTN);
----转换为二进制
LOOP
V_N2 := MOD(V_N1, 2);
V_N1 := ABS(TRUNC(V_N1 / 2));
V_RTN := TO_CHAR(V_N2) || V_RTN;
EXIT WHEN V_N1 = 0;
END LOOP;
--dbms_output.put_line('负数转换结果'||V_RTN);
--补全32位高位0
SELECT lpad(V_RTN,32,0)
INTO V_RTN
FROM dual;
--dbms_output.put_line('负数补全0结果'||V_RTN);
END IF;
RETURN V_RTN;
END;