2009-12-01 21 views
5

Estoy tratando de escribir un pequeño programa que tiene que almacenar y recuperar valores de la base de datos. La base de datos es objeto relacional.¿Cómo lidiar con VARRAY (Oracle 9i) en JDBC?

declaraciones Acá el DDL:

create or replace type Guy as object (name varchar(80), address varchar(80), dateOfBirth date) 

create or replace type KnownLanguages as varray(10) of varchar(80) 

create table Coders (person_ Guy, description clob, knownLanguages_ KnownLanguages) 

y este es mi código Java:

package adbms; 

import java.sql.Clob; 
import java.sql.Connection; 
import java.sql.Date; 
import java.sql.DriverManager; 
import java.sql.PreparedStatement; 
import java.sql.ResultSet; 
import java.sql.SQLException; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.Scanner; 

import oracle.jdbc.OracleDriver; 
import oracle.jdbc.driver.OraclePreparedStatement; 
import oracle.jdbc.driver.OracleResultSet; 
import oracle.sql.ARRAY; 
import oracle.sql.ArrayDescriptor; 

public class SimpleJdbcApplication { 
    public static final String DRIVER_TYPE = "thin"; 
    public static final String HOST_NAME = "localhost"; 
    public static final int PORT = 1521; 
    public static final String DATABASE_SID = "ralphdb"; 
    public static final String USER_NAME = "scott"; 
    public static final String PASSWORD = "tiger"; 
    public static final String URL = String.format("jdbc:oracle:%s:@%s:%d:%s", DRIVER_TYPE, HOST_NAME, PORT, DATABASE_SID); 

    private static Connection connection; 
    private static Scanner read; 
    private static PreparedStatement insertStatement; 
    private static PreparedStatement deleteStatement; 
    private static PreparedStatement updateStatement; 
    private static PreparedStatement displayStatement; 

    static { 
     try { 
      System.out.println(URL); 
      read = new Scanner(System.in); 
      DriverManager.registerDriver(new OracleDriver()); 
      connection = DriverManager.getConnection(URL, USER_NAME, PASSWORD); 
      insertStatement = connection.prepareStatement("insert into Coders values(Guy(?,?,?) , ? , ?)"); 
      deleteStatement = connection.prepareStatement("delete from Coders where person_.name=?"); 
      updateStatement = connection.prepareStatement("update Coders set person_.name=? where person_.name=?"); 
      displayStatement = connection.prepareStatement("select * from Coders"); 
     } catch (Exception x) { 
      x.printStackTrace(); 
     } 
    } 

    public static void main(String... args) throws SQLException { 
     while (true) { 
      System.out.println("Enter your choice."); 
      System.out.println("1. Insert"); 
      System.out.println("2. Delete"); 
      System.out.println("2. Update"); 
      System.out.println("4. Display"); 
      System.out.println("5. Enter a direct query"); 
      System.out.println("6. Exit"); 
      switch (read.nextInt()) { 
       case 1: 
        insertCoder(); 
        break; 
       case 2: 
        removeCoder(); 
        break; 
       case 3: 
        updateCoder(); 
        break; 
       case 4: 
        displayAllCoders(); 
        break; 
       case 5: 
        processDirectQuerry(); 
        break; 
       default: 
        System.exit(0); 
      } 
     } 
    } 

    private static void processDirectQuerry() throws SQLException { 
     System.out.println("Enter the query."); 
     String query = read.nextLine(); 
     connection.createStatement().execute(query); 
    } 

    private static void displayAllCoders() throws SQLException { 
     ResultSet resultSet = displayStatement.executeQuery(); 
     System.out.println("Name\tAddress\tDate of birth\tDescription\tKnown Languages"); 
     while (resultSet.next()) { 
      System.out.print(resultSet.getString("person_.name")+"\t"); 
      System.out.print(resultSet.getString("person_.address")+"\t"); 
      System.out.print(resultSet.getDate("person_.dateOfBirth")+"\t"); 
      Clob description = resultSet.getClob("description"); 
      System.out.print(description.getSubString(1L, (int) description.length())); 
      ARRAY oraArray = ((OracleResultSet) resultSet).getARRAY("knownLanguages_"); 
      String[] languagesArray = (String[]) oraArray.getArray(); 
      for (String language : languagesArray) { 
       System.out.print(language + " "); 
      } 
      System.out.println(); 
     } 
    } 

    private static void updateCoder() throws SQLException { 
     System.out.println("Enter the name of the coder whose name is to be updated."); 
     String originalName = read.nextLine(); 
     System.out.println("ENter the new name."); 
     String newName = read.nextLine(); 
     updateStatement.setString(1, newName); 
     updateStatement.setString(2, originalName); 
     updateStatement.executeUpdate(); 
    } 

    private static void removeCoder() throws SQLException { 
     System.out.println("Enter the name of coder to be removed."); 
     String name = read.nextLine(); 
     deleteStatement.setString(1, name); 
     deleteStatement.executeUpdate(); 
    } 

    private static void insertCoder() throws SQLException { 
     read = new Scanner(System.in); 
     System.out.println("Enter the name, address and date of birth."); 
     String name = read.nextLine(); 
     String address = read.nextLine(); 
     String dateOfBirth = read.nextLine(); 
     System.out.println("Enter a brief description."); 
     String description = read.nextLine(); 
     List<String> languagesList = new ArrayList<String>(); 
     System.out.println("Enter names of known languages. (At most 10.) Type 'done' when you're done."); 
     String token = null; 
     int i = 0; 
     while (i < 10 && !(token = read.nextLine()).equalsIgnoreCase("done")) { 
      languagesList.add(token); 
        i++; 
     } 
     insertStatement.setString(1, name); 
     insertStatement.setString(2, address); 
     insertStatement.setDate(3, Date.valueOf(dateOfBirth)); 
     insertStatement.setString(4, description); 
     //String[] languagesArray = (String[]) languagesList.toArray(); 
     Object[] languagesArray = languagesList.toArray(); 
     ArrayDescriptor arrayDescriptor = ArrayDescriptor.createDescriptor("KnownLanguages", connection); 
     ARRAY oraArray = new ARRAY(arrayDescriptor, connection, languagesArray); 
     ((OraclePreparedStatement) insertStatement).setARRAY(5, oraArray); 
     insertStatement.executeUpdate(); 
    } 
} 

El código compila bien. Pero cuando trato de insertar valores en la base de datos, se da el siguiente error

F: \ adb> SimpleJdbcApplication java jdbc: oracle: thin: @ 127.0.0.1: 1521: ralphdb Introduzca su elección. 1. Insertar 2. Eliminar 2. Actualizar 4. Pantalla 5. Introduzca una consulta directa 6. Salir 1 Introduzca el nombre, dirección y fecha de nacimiento. rahul mumbai 1989-12-22 Ingrese una breve descripción. feliz Ingrese nombres de idiomas conocidos. (Como máximo 10.) Escriba 'hecho' cuando haya terminado. C++ c java Excepción en hilo hecho "principal" java.sql.SQLException: nombre no válido patrón: SYSTEM.K nownLanguages ​​ en oracle.jdbc.driver.DatabaseError.throwSqlException (DatabaseError.java : 112) en oracle.jdbc .driver.DatabaseError.throwSqlException (DatabaseError.java : 146) en oracle.jdbc.oracore.OracleTypeADT.initMetadata (OracleTypeADT.java:463 ) en oracle.jdbc.oracore.OracleTypeADT.init (OracleTypeADT.java:362) en oracle.sql.ArrayDescriptor.initPickler (ArrayDescriptor.java:1756) en oracle.sql.ArrayDescriptor. (ArrayDescriptor.java:272) en oracle.sql.ArrayDescriptor.createDescriptor (ArrayDescriptor.jav a: 196) en oracle.sql.ArrayDescriptor.createDescriptor (ArrayDescriptor.java:165) en oracle.sql.ArrayDescriptor.createDescriptor (ArrayDescriptor.java:150) en oracle.sql.ArrayDescriptor.createDescriptor (ArrayDescriptor.java: 115) en SimpleJdbcApplication.insertCoder (SimpleJdbcApplication.java:143) en SimpleJdbcApplication.main (SimpleJdbcApplication.java:62) F: \ adb>

Creo que hay algo mal con la forma en que han manejado la VARRAY. Por favor, ayúdenme ...

¡Gracias! :-)

Respuesta

1

Parece ser esta línea lanzar la excepción:

ArrayDescriptor arrayDescriptor = ArrayDescriptor.createDescriptor("KnownLanguages", connection); 

Creo que el problema es que no está resolviendo el nombre del tipo de la base de datos. Creo que encontré en el pasado que la búsqueda de tipo distingue mayúsculas de minúsculas y, de forma predeterminada, en Oracle, el nombre del tipo es mayúsculo. Intente usar "KNOWNLANGUAGES" en la línea anterior.

Además, parece estar buscando en el esquema del SISTEMA, aunque no sé por qué. Si el tipo no es propiedad de SYSTEM, es posible que deba especificarlo explícitamente en la llamada del descriptor también (por ejemplo, "SCOTT.KNOWNLANGUAGES").

Cuestiones relacionadas