Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Creating Java Functions for Oracle Step 1: Create and test the function(s) Oracle can only get at static functions in a class. These static functions can create objects or write to files but not do things like write to standard output. (A call to System.out or System.in would fail.) Consider the following code example that we went over in class: We created 2 static functions: rand and quoteIt along with a main routine to test it. Although advanced debugging is available for java functions embedded in Oracle (ie: JDeveloper), we are not spending enough time on this topic to make it worth while for us to learn the environment. Therefore we try to test our functions in a pure java environment by placing test code in the main procedure. Compile and run the functions: //create or replace and compile //java source named rnum //as import java.io.*; import java.util.*; import javax.swing.*; import java.lang.*; class rnumDemo { //Couldn't find a PI constant - wrote it in as a function //with no arguments. public static Double PI() {return new Double(Math.PI); } public static Integer rand(Integer num) { return new Integer( (int) (Math.random()*num.intValue()) + 1); } public static String quoteIt(String s) { return "" + '"'+s+'"'; } /* THIS IS NEW! Contrary to what I said in class you CAN do output to the screen n a function However, you do need to execute the following SQLPLUS: statements: set serveroutput on exec dbms_java.set_output(10000); */ public static String debugHello() { System.out.println("Hello: trace message"); return "World"; } //Testing outside of Oracle! Make sure you do this! public static void main(String[] argv) { System.out.println(rand(new Integer(17))); System.out.println(rand(new Integer(17))); System.out.println(rand(new Integer(27))); System.out.println(rand(new Integer(27))); System.out.println(quoteIt("Hello World")); System.out.println("The value of PI is: "+PI()); System.out.println(debugHello()); } } } Step 2: Loading the functions into Oracle This is an Oracle specific routine though db2 and Sybase have similar procedures. At the Unix command prompt type in: loadjava -v -f -user username/password -resolve rnumDemo.java The -v option just means “verbose” - tell me what's happening while its happening. You need it to tell you that the java code was successfully loaded; otherwise you don't get any feedback. The -f option means “force it” - If the function is already in the database -f forces the new code to replace the old code. If the function is not already in the database it makes no difference. -user You have to give a valid authorization. -resolve - Check for (resolve) references to functions that are already stored in the user’s schema. This is not needed in our current example. The last argument is your program's source file. Note that you could also use a .jar file to bundle in several classes and functions. .class files are loaded but Oracle has trouble finding the function. You’d also be advised to use the same level of JDK as Oracle uses. Therefore is a better idea to load a validated source file rather than a compiled file – Oracle will then compile it on first use, using its own internal version of javac. To find out more about the loadjava utility type in: loadjava -help The complementary function dropjava removes the loaded file from Oracle. Script files ldjava and dropjava prompt for your user id and password and keep the password hidden. They are just a convenience and not absolutely necessary. Step 3: Define for Oracle how the function will be used: create or replace function rand(x Integer) return number as language java name 'rnum.random(java.lang.Integer) return java.lang.Integer'; / Notes: 1. This syntax should be supported in other databases. Probably not yet part of mySql. Languages other than java are also supported (ie: C, C++, PL/SQL in the case of Oracle). Do not expect SQL Server (Microsoft) to support java. There are extra sub clauses to the “create or replace function” statement that are proprietary to specific datbase vendors. 2. You need 2 terminators on this statement. The semicolon terminates the name clause – slash terminates the create clause. This requirement does happen elsewhere in Oracle – it is a pain to remember and deal with. 3. The name of the function is rand as far as Oracle is concerned. The first part of the “create or replace” function describes how Oracle sees the function. The 2nd half describes how the function is viewed by java. 4. Note the use of Oracle data types in the first half of the statement, and java data types for the part of the statement that is in quotes. The idea is to tell Oracle how to convert the types. For now use the following type correspondences Oracle Type varchar2 number Date Timestamp Java Type1 java.lang.String java.lang.Double, java.lang.Float, java.lang.Integer, java.math.BigDecimal2 Java.sql.Date Java.sql.Timestamp 5. Arguments to java functions and should be fully qualified types, ie: java.lang.Double. The return types should also be fully qualified – according to Oracle’s current documentation. – however it is better to be safe 1 http://download-east.oracle.com/docs/cd/B14117_01/java.101/b12021/pub.htm#i1006574 will list a full set of mappings between Oracle and Java data types 2 BigDecimal is recommended because Oracle's numeric fields are coded as binary coded decimal (BCD) and can have a greater accuracy than Java's Double or Integer. For our needs we can get away with the more familiar classes. 6. Use Objects not primitive types. This is to allow NULL values to be passed back and forth. ints, floats, doubles are allowed (they work with Oracle’s number type) but not recommended. 7. SQL for defining the other examples are online. Step 4: Testing the function in SQLPLUS At the SQL> prompt type in: desc rand Select rand(20) from dual; run run run The desc command describes the arguments to the function and its return value. Take the same approach to test the quoteIt function. Data Dictionary Notes The first time you run loadjava the table CREATE$JAVA$LB$TABLE is created in your schema to store your java code. To view the tables and views associated with java: select view_name “Views and Table” from all_views where view_name like '%JAVA%' union select table_name from all_tables where table_name like '%JAVA%'; To view a list of your defined methods: select name, method_name from all_java_methods where owner=user; The names of your methods will not appear in this table until AFTER the methods have been compiled (ie: after the 1st use of the methods in Oracle).