Nah, jika "tampaknya digunakan" maka masuk akal untuk melakukan sedikit rekayasa balik dan memeriksa apa sebenarnya yang disebut dan membongkar kode fungsi tersebut.
Namun, jika Anda ingin mendalami internal Oracle, berikut ini mungkin bisa membantu.
Pertama-tama, Anda harus mencari tahu apa fungsi C internal yang dipanggil. Untuk melakukannya, Anda dapat mengeksekusi beberapa kode yang berjalan lama dalam satu sesi. Saya menjalankan ini
select avg(ora_hash(rownum)) id from
(select rownum from dual connect by rownum <= 1e4),
(select rownum from dual connect by rownum <= 1e4);
Ini juga bisa berupa kode PL/SQL, Anda hanya perlu memastikan bahwa Anda terus-menerus memanggil ora_hash.
Saat sedang berjalan
-
Jika Anda menggunakan Windows maka Anda dapat menggunakan ostackprof by TANEL PODER(https://blog.tanelpoder.com/2008/10/31/advanced-Oracle-troubleshooting-guide-part-9-process-stack -profiling-from-sqlplus-using-ostackprof/ )
-
Jika Anda menggunakan *nix maka Anda dapat menggunakan dtrace(http://www.Oracle.com/technetwork/articles/servers-storage-dev/dtrace-on-linux-1956556.html ), Grafik Api (skenario penggunaan https://blog.dbi -services.com/Oracle-database-multilingual-engine-mle/ )
Saya menguji pada Windows dan sepertinya ora_hash adalah ...->evaopn2()->evahash() ->...
Sekarang mari kita google untuk evahash. Kami sangat beruntung karena ada file header di situs resmi https://oss.Oracle.com/projects/ocfs-tools/src/branches/new-dir-format/libocfs/Linux/inc/ocfshash.h dengan tautan ke evahash.
Dan akhirnya ada halaman dengan kode C yang sebenarnya http://burtleburtle.net/bob/hash/ evahash.html
Sejauh ini bagus, kami ingat bahwa kami dapat menggunakan fungsi C eksternal di Oracle jika kami membangunnya ke dalam perpustakaan (DLL di Windows).
Misalnya pada Win x64 saya jika saya mengubah tanda tangan fungsi menjadi
extern "C" ub4 hash( ub1 *k, ub4 length, ub4 initval)
itu bisa berhasil dieksekusi dari Oracle. Tapi, seperti yang Anda lihat, tanda tangan sedikit berbeda dari ora_hash di Oracle. Fungsi ini menerima nilai, panjangnya, dan initvalnya (dapat berupa seed) sedangkan signature di Oracle adalah ora_hash(expr, max_bucket, seed_value).
Mari kita coba mengujiOracle
SQL> select ora_hash(utl_raw.cast_to_raw('0'), power(2, 32) - 1, 0) oh1,
2 ora_hash('0', power(2, 32) - 1, 0) oh2,
3 ora_hash(0, power(2, 32) - 1, 0) oh3,
4 ora_hash(chr(0), power(2, 32) - 1, 0) oh4
5 from dual;
OH1 OH2 OH3 OH4
---------- ---------- ---------- ----------
3517341953 3517341953 1475158189 4056412421
C
int main()
{
ub1 ta[] = {0};
ub1* t = ta;
cout << hash(t, 1, 0) << endl;
ub1 ta0[] = {'0'};
ub1* t0 = ta0;
cout << hash(t0, 1, 0) << endl;
return 0;
}
1843378377
4052366646
Tidak ada angka yang cocok. Jadi apa masalahnya?ora_hash menerima parameter dari hampir semua jenis (misalnya select ora_hash(sys.odcinumberlist(1,2,3)) from dual
) sementara fungsi C menerima nilai sebagai array byte. Ini berarti bahwa beberapa konversi terjadi sebelum pemanggilan fungsi. Jadi sebelum menggunakan fungsi hash C yang disebutkan, Anda harus mengetahui bagaimana nilai aktual diubah sebelum meneruskannya.
Anda dapat melanjutkan dengan rekayasa balik binari Oracle menggunakan IDA PRO + sinar hex tetapi itu mungkin memakan waktu berhari-hari. Belum lagi detail spesifik platform.
Jadi jika Anda ingin meniru ora_hash, opsi termudah adalah menginstal Oracle express edition dan menggunakannya untuk memanggil ora_hash.
Saya harap itu menarik. Semoga berhasil.
Perbarui
ora_hash dan dbms_utility.get_hash_value dapat dipetakan satu sama lain (lihat https:// /jonathanlewis.wordpress.com/2009/11/21/ora_hash-function/ )
SQL> select dbms_utility.get_hash_value('0', 0 + 1, 1e6 + 1) ha1,
2 ora_hash('0', 1e6, 0) + 1 ha2
3 from dual;
HA1 HA2
---------- ----------
338437 338437
Jika kita membuka isi paket dbms_utility kita akan melihat deklarasi berikut
function get_hash_value(name varchar2, base number, hash_size number)
return number is
begin
return(icd_hash(name, base, hash_size));
end;
dan
function icd_hash(name varchar2,
base binary_integer,
hash_size binary_integer) return binary_integer;
pragma interface(c, icd_hash);
Ayo cari di Google untuk icd_hash
dan kami dapat menemukan bahwa itu dipetakan ke _psdhsh
(https://yurichev.com/blog/50/
). Sekarang saatnya membongkar oracle.exe dan mengekstrak kode untuk _psdhsh
dari itu. Mungkin saya akan meluangkan waktu untuk ini tahun depan.