Как бороться с VARRAYs (Oracle 9i) в JDBC? - PullRequest
5 голосов
/ 01 декабря 2009

Я пытаюсь написать небольшую программу, которая должна хранить и извлекать значения из базы данных. База данных является объектно-реляционной.

Вот операторы 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)

А это мой код 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();
    }
}

Код компилируется нормально. Но когда я пытаюсь вставить значения в базу данных, это выдает следующую ошибку

F: \ adb> java SimpleJdbcApplication JDBC: оракул: тонкий: @ 127.0.0.1: 1521: ralphdb Введите ваш выбор. 1. Вставьте 2. Удалить 2. Обновление 4. Дисплей 5. Введите прямой запрос 6. Выход 1 Введите имя, адрес и дату рождения. Рахул Мумбаи 1989-12-22 Введите краткое описание. счастливый ввод названия известных языков. (В большинстве 10.) Введите «готово», когда вы закончите. c ++ c java сделано Исключение в потоке "main" java.sql.SQLException: неверное имя pattern: SYSTEM.K nownLanguages в oracle.jdbc.driver.DatabaseError.throwSqlException (DatabaseError.java : 112) в oracle.jdbc.driver.DatabaseError.throwSqlException (DatabaseError.java : 146) в oracle.jdbc.oracore.OracleTypeADT.initMetadata (OracleTypeADT.java:463 ) в oracle.jdbc.oracore.OracleTypeADT.init (OracleTypeADT.java:362) в oracle.sql.ArrayDescriptor.initPickler (ArrayDescriptor.java:1756) в oracle.sql.ArrayDescriptor. (ArrayDescriptor.java:272) в oracle.sql.ArrayDescriptor.createDescriptor (ArrayDescriptor.java:196) в oracle.sql.ArrayDescriptor.createDescriptor (ArrayDescriptor.java:165) в oracle.sql.ArrayDescriptor.createDescriptor (ArrayDescriptor.java:150) в oracle.sql.ArrayDescriptor.createDescriptor (ArrayDescriptor.java:115) в SimpleJdbcApplication.insertCoder (SimpleJdbcApplication.java:143) в SimpleJdbcApplication.main (SimpleJdbcApplication.java:62) F: \ ADB>

Я думаю, что-то не так с тем, как я справился с VARRAY. Пожалуйста, помогите мне ...

Спасибо! : -)

1 Ответ

1 голос
/ 01 декабря 2009

Похоже, эта строка выдает исключение:

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

Я думаю, проблема в том, что он не разрешает имя типа в базе данных. Я полагаю, что в прошлом я обнаружил, что поиск типов чувствителен к регистру, и по умолчанию в Oracle имя типа все в верхнем регистре. Поэтому попробуйте использовать «KNOWNLANGUAGES» в приведенной выше строке.

Кроме того, похоже, что это выглядит в схеме SYSTEM, хотя я не знаю почему. Если тип не принадлежит SYSTEM, вам может потребоваться явно указать это в вызове дескриптора (например, «SCOTT.KNOWNLANGUAGES»).

...