Si recientemente hemos actualizado la version de Oracle a una 12.2 o superior, nos encontraremos con un problema. A partir de la 12.2 Oracle ya no soporta ejecuciones SQLJ.
https://docs.oracle.com/en/database/oracle/oracle-database/18/jsqlj/changes-this-release-oracle-sqlj-developers-guide.html
Desupported Features
The following features are no longer supported by Oracle:
SQLJ in the Server
Starting with Oracle Database 12c Release 2 (12.2), Oracle does not support server-side SQLJ code.
Oracle supports using client-side SQLJ. However, Oracle does not support the use of server-side SQLJ, including running stored procedures, functions, and triggers in the database environment.
Esto es un gran problema si por ejemplo, utilizamos funciones para leer ficheros locales desde un procedimiento. Existe un procedimiento de lectura de ficheros muy común entre los DBA que nos permite leer ficheros locales a partir de pasarle como parámetro el directorio y el patrón de búsqueda (wildcard).
La famosa función se llama DIRLIST pero cuando cuando la ejecutamos en una Oracle 12.2 nos mostrará el siguiente mensaje:
Errors for JAVA SOURCE "DirList":
LINE/COL ERROR
-------- -----------------------------------------------------------------
0/0 An exception has occurred in the compiler (1.8.0_181). Please
file a bug against the Java compiler via the Java bug reporting
page (http://bugreport.java.com) after checking the Bug Database
(http://bugs.java.com) for duplicates. Include your program and
the following diagnostic in your report. Thank you.
0/0 at oracle.aurora.rdbms.Compiler.compile(Compiler.java:317)
0/0 at
com.sun.tools.javac.util.JCDiagnostic.<init>(JCDiagnostic.java:41
2)
Esto se debe a lo que comentaba, a partir de la version 12.2 Oracle no permite ejecuciones SQLJ del lado del servidor de BBDD.
Un código de ejemplo de DirList que funciona en versiones <12.1 es el siguiente:
CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED MOSTRARFICHEROS as import java.io.*;
import java.sql.*;
public class DirList {
public static void lista(String directory)
throws SQLException {
File[] files = new File(directory).listFiles();
java.lang.String element;
for (File file : files) {
if (file.isFile()) {
element = file.getName();
#sql {INSERT INTO DIR_LIST (x) VALUES (:element)};
}
}
};
}
/
Ahora bien, con una pequeña modificación podemos hacerlo compatible con 12.2 de la siguiente manera:
CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED MOSTRARFICHEROS as
import java.io.*;
import java.sql.*;
public class DirList {
public static void lista(String directory)
throws SQLException {
Connection conn = DriverManager.getConnection("jdbc:default:connection:");
String sql = "INSERT INTO DIR_LIST (x) VALUES (?)";
File path = new File(directory);
String[] list = path.list();
String element;
for (int i = 0; i < list.length; i++) {
element = list[i];
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, element);
pstmt.executeUpdate();
pstmt.close();
}
}
}
/
Tendremos que crear un procedimiento para cargarlo en una lista:
create or replace procedure
MOSTRAR_FICHEROS( DIRECTORIO in varchar2)
as language java
name 'DirList.lista(java.lang.String)';
/
Hay que asignar los permisos pertinentes (actualizar el usuario de bbdd):
DECLARE
KEYNUM NUMBER;
BEGIN
SYS.DBMS_JAVA.GRANT_PERMISSION(
grantee => 'USUARIOBBDD'
,permission_type => 'SYS:java.io.FilePermission'
,permission_name => '<<ALL FILES>>'
,permission_action => 'read ,write, execute, delete'
,key => KEYNUM
);
END;
/
Luego para probarlo simplemente podemos ejecutar:
SQL> exec MOSTRAR_FICHEROS('/home/oracle');
PL/SQL procedure successfully completed.
SQL> select * from MOSTRARFICHEROS where rownum <=3;
X
------------------------------
1.TXT
2.TXT
0 comentarios:
Publicar un comentario