Oracle Tips : How Oracle execute OS Command via java
Oracle Tips : How Oracle execute OS Command via java
สวัสดีตอนกลางคืนครับ พอดีว่าวันนี้กำลังทดสอบงานอยู่แล้วก็นึกถึง Tips อันนึงน่าสนใจ เกี่ยวกับการเรียกใช้
คำสั่งบนระบบปฏิบัติการ (อะไรก็ได้) ผ่าน Oracle Database ซึ่งเป็นเกล็ดที่คิดว่ามีประโยชน์มากๆสำหรับผู้ดูแลระบบฐานข้อมูล (DBA) หรือผู้พัฒนาระบบก็ตาม
หลักการก็คือ Oracle Database สามารถเรียกใช้ Java Class ได้ เพราะฉะนั้นถ้าเราสร้าง Java source ใน oracle database จากนั้นเราก็ค่อยสร้าง Package หรือ Procedure มา call java อีกที
แต่ทว่า…ผมไม่ใช่ developer or java programmer ก็เลยเขียน java source ไม่ได้ ก็เลยไปถามผู้รู้ (google) แล้วก็ได้ source มาพร้อมกับการติดตั้งง่ายๆ ดังนี้
ตัวอย่าง สมมติว่าผมต้องการสร้าง Java Source, Package Call Java บน user “SHARE_SERVICE” จะมีขั้นตอนดังนี้
1. Login to Oracle as “SYS” or “SYSTEM”
2. Create procedure “GRANT_JAVA_PERMISSION”
ขั้นตอนนี้ทำครั้งเดียว เพราะเป็นการสร้าง procedure สำหรับไว้ให้สิทธิการจัดการเกี่ยวกับ JAVA Permission
ดาว์นโหลดโค้ดนี้ไปรัน cr_grant_java_perm.zip
NOTE:
มี permission ที่อันตรายอยู่คือ การให้สิทธิรันได้ทุก OS Command ดังนั้น หากเราจะใช้ procedure ให้สิทธิ user ไหนก็ต้องระมัดระวังด้วย หรือหากเราจะปิดการให้สิทธินี้ก็ comment ไว้ได้ ที่บรรทัดข้างล่างนี้ครับ
— allows the DB user to execute ALL OS Commands – very dangerous! — dbms_java.grant_permission(grantee => v_grantee, permission_type => ‘SYS:java.io.FilePermission’, permission_name => ‘<<ALL FILES>>’, permission_action => ‘execute’ ); |
เมื่อรันสร้าง procedure เสร็จแล้วให้เรียกใช้ดังนี้
SQL> exec grant_java_permission(‘SHARE_SERVICE’);
3. Login as user “SHARE_SERVICE”
เมื่อให้สิทธิแล้วก็จะมาทำการสร้าง Java Source , Package OS_COMMAND กัน โดยผมมี script file แนบรันได้เลยครับ ดาว์นโหลดตรงนี้ os_command_java.zip
4. TESTING
เมื่อสร้างเสร็จแล้วก็ทดสอบกันเลยครับ สมมติว่าตอนนี้ (current user = SHARE_SERVICE)
exam4.1 : ถ้าเราต้องการเห็นผลลัพธ์ ให้เรียกใช้ function os_command.exec_clob() ดังนี้
SQL> select os_command.exec_clob(‘/bin/date’) from dual;
OS_COMMAND.EXEC_CLOB(‘/BIN/DATE’) |
exam4.2 : ถ้าเราไม่ต้องการเห็นผลลัพธ์ (เผื่อบางทีต้องการเช็คแค่ว่าทำสำเร็จหรือไม่) ก็เรียกใช้ function
os_command.exec(); โดยถ้าทำสำเร็จจะ return= 0, แต่ถ้าไม่สำเร็จจะมีค่า > 0 ดังนี้
SQL> select os_command.exec(‘/bin/date’) from dual;
OS_COMMAND.EXEC(‘/BIN/DATE’) |
SQL> select os_command.exec(‘/tmp/scr.sh’) from dual;
OS_COMMAND.EXEC(‘/TMP/SCR.SH’) |
ตัวอย่างเป็นการเรียกรัน shell script แต่ไม่ได้ใส่ tag ” #!/bin/sh ” ในไฟล์ shell script ก็เลยรันไม่ได้ครับ แต่
เท่าที่ทดสอบมา ถึงแม้ว่าจะมี tag header และรันได้ก็ตาม แต่ก็ไม่ได้ผลลัพธ์ เหมือนกับว่ารันไฟล์ได้เฉยๆ แต่ไม่ได้รัน
คำสั่งภายใน script ไฟล์
5. Grant package OS_COMMAND to other users
สมมติว่า ผมต้องการให้ user = KOKIT ต้องการเรียกใช้ด้วย ทำได้ดังนี้
1. Login as “SYS” or “SYSTEM”
2. ให้สิทธิเรียกใช้ Java ตามขั้นตอนที่ 2 แต่เปลี่ยนเป็น user = KOKIT ดังนี้
SQL> exec grant_java_permission(‘KOKIT’);
3. Login as owner java source ( ในที่นี้คือ user “SHARE_SERVICE” )
แล้วให้สิทธิดังนี้
SQL> grant execute on java source os_helper to KOKIT;
SQL> grant execute on “ExternalCall” to KOKIT ;
SQL> grant execute on os_command to KOKIT;
NOTE:
แต่ถ้าต้องการให้ทุกคนใช้เราอาจ grant ให้ public ได้ โดยเรียก script นี้รัน grant_public.zip
4. Login as destination user “KOKIT”
SQL> create synonym OS_COMMAND for SHARE_SERVICE.OS_COMMAND ;
เท่านี้เราก็เรียกใช้ package os_command ได้แล้วครับ ยังไงทดลองใช้ดูครับ