Изменить соединение базы данных с Java для нескольких таблиц в Crystal Reports - PullRequest
3 голосов
/ 23 января 2012

Мы используем Crystal Reports XI, и я сгенерировал простой отчет с одной таблицей. Во время создания отчета я подключился к нашей базе данных разработки с ODBC. Теперь я хотел изменить источник данных во время выполнения в Java, чтобы подключиться к другой нашей базе данных.

Итак, я создал метод для изменения источника данных. Потому что мы используем разные системы баз данных (infomix, oracle и mysql).

private ReportClientDocument replaceDatabaseConnection(ReportClientDocument doc,  Database database, String ip, String port, String dbname, String dbservername, String username, String passwort, String userOrSchemaName) {
    StopWatch sw = new StopWatch();
    try {       

        for (int i = 0; i < doc.getDatabaseController().getDatabase().getTables().size(); i++) {
            ITable table = doc.getDatabaseController().getDatabase().getTables().get(i);
            sw.start(table.getName());


            System.out.println("processing table : " + table.getName());

            // dbane.owner.tablename
            String original_qualifiedName = table.getQualifiedName();
            String new_qualifierName = original_qualifiedName;

            switch (database) {
            case ORACLE:
                // SCHEMA.TABLENAME
                String tableName = StringUtils.substringAfterLast(original_qualifiedName, ".").toUpperCase();
                new_qualifierName = userOrSchemaName.toUpperCase()+"."+tableName;
                break;
            case INFORMIX:
                // DATABASE.OWNER.TABLENAME
                new_qualifierName = dbname + ":" + userOrSchemaName + "." + StringUtils.substringAfterLast(original_qualifiedName, ".");                    

                break;
            case MYSQL:
                // DATABASE.OWNER.TABLENAME
                new_qualifierName = dbname + "." + userOrSchemaName + "." + StringUtils.substringAfterLast(original_qualifiedName, ".");                    
                break;
            default:
                break;
            }

            String jdbcConnectionString = null;
            String preQEServerName = null;
            String driver = null;

            switch (database) {
            case INFORMIX:
                // !com.informix.jdbc.IfxDriver!jdbc:informix-sqli://localhost:40421/export:INFORMIXSERVER=cargool1!user={userid}!password={password}
                jdbcConnectionString = "!com.informix.jdbc.IfxDriver!jdbc:informix-sqli://"+ip+":"+port+"/"+dbname+":INFORMIXSERVER="+dbservername+"!user={userid}!password={password}";
                // jdbc:informix-sqli://localhost:40421/export:INFORMIXSERVER=cargool1
                preQEServerName      = "jdbc:informix-sqli://"+ip+":"+port+"/"+dbname+":INFORMIXSERVER="+dbservername;
                // com.informix.jdbc.IfxDriver
                driver = "com.informix.jdbc.IfxDriver";
                break;
            case MYSQL:
                // !com.mysql.jdbc.Driver!jdbc:mysql://172.20.9.170:3306/hego
                jdbcConnectionString = "!com.mysql.jdbc.Driver!jdbc:mysql://"+ip+":"+port+"/"+dbname;
                // jdbc:mysql://172.20.9.170:3306/customer
                preQEServerName      = "jdbc:mysql://"+ip+":"+port+"/"+dbname;
                // com.mysql.jdbc.Driver
                driver = "com.mysql.jdbc.Driver";
                break;
            case ORACLE:
                // !oracle.jdbc.driver.OracleDriver!jdbc:oracle:thin:@//localhost:50000/tmsddb2
                jdbcConnectionString = "!oracle.jdbc.driver.OracleDriver!jdbc:oracle:thin:@//"+ip+":"+port+"/"+dbname;
                // jdbc:oracle:thin:@//localhost:50000/tmsddb2
                preQEServerName      = "jdbc:oracle:thin:@//"+ip+":"+port+"/"+dbname;
                // "oracle.jdbc.driver.OracleDriver"
                driver = "oracle.jdbc.driver.OracleDriver";
                break;
            default:
                break;
            }



    System.out.println("Qualfied Name : "+ table.getQualifiedName());
    table.setQualifiedName(new_qualifierName);

    ConnectionInfo newConnectionInfo = new ConnectionInfo();

    PropertyBag boPropertyBag1 = new PropertyBag();

    boPropertyBag1.put("JDBC Connection String", jdbcConnectionString);
    boPropertyBag1.put("PreQEServerName",   preQEServerName);
    boPropertyBag1.put("Server Type", "JDBC (JNDI)");
    boPropertyBag1.put("Database DLL", "crdb_jdbc.dll");
    boPropertyBag1.put("Database", dbname);
    boPropertyBag1.put("Database Class Name", driver);
    boPropertyBag1.put("Use JDBC", "true");
    boPropertyBag1.put("Database Name", dbname);
    boPropertyBag1.put("Server Name", preQEServerName);
    boPropertyBag1.put("Connection URL", preQEServerName);
    boPropertyBag1.put("Server", null);

    newConnectionInfo.setAttributes(boPropertyBag1);
    newConnectionInfo.setUserName(username);
    newConnectionInfo.setPassword(passwort);

    table.setConnectionInfo(newConnectionInfo);

            doc.getDatabaseController().setTableLocation(table, doc.getDatabaseController().getDatabase().getTables().get(i));
            System.out.println("***************************DONE********************************");
            sw.stop();
        }
        return doc;

    } catch (Exception ex) {
        System.out.println(ExceptionUtils.getFullStackTrace(ex));
    }


    System.out.println(sw.prettyPrint());

    return doc;

}

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

Но если в отчете более одной таблицы, я получаю странные ошибки подключения к базе данных из-за неправильного имени пользователя / пароля Имя пользователя из исключения полностью неверно (это не имя пользователя, которое я передал методу).

com.crystaldecisions.sdk.occa.report.lib.ReportSDKLogonException: Fehler bei Anmeldung: неверный пароль или пользователь com.informix.asf.IfxASFRemoteException: username @ employee-nb1 не известен на сервере базы данных .--- - Код ошибки: -2147217393 Имя кода ошибки: dbLogonFailed

Во-первых, я не хотел подключаться к базе данных informix. Я передал методу параметр mysql. Исключение составляет информация о базе данных, к которой я подключился при создании отчета (через ODBC).

Следующая странная вещь заключается в том, что username @ employee-nb1 Имя пользователя - это имя пользователя, которое я вошел в базу данных при создании отчета, и наиболее раздражающим является emplyee-nb1. Это название одного ноутбука в нашей компании, но оно не имеет ко мне никакого отношения. Отчет никогда не был открыт / создан на компьютере, и на этом компьютере также не запущен процесс Java.

Как я уже сказал, если я использую отчет (созданный таким же образом) только с одной таблицей, все работает нормально. При наличии более одной таблицы я получаю эту ошибку. И я пока не использую никаких подотчетов.

У кого-нибудь есть идеи?

Вот как я называю метод

    private void createReport8() {
    ReportClientDocument doc = new ReportClientDocument();

    try {
        doc.setReportAppServer(ReportClientDocument.inprocConnectionString);
        doc.open("C:\\dev\\reports\\003_jdbc_informix_3_tabellen.rpt",OpenReportOptions._openAsReadOnly);

        changeDataSource(doc, null, null, "username", "******", "!com.mysql.jdbc.Driver!jdbc:mysql://172.20.9.170:3306/customerdb", "com.mysql.jdbc.Driver", null);

        PDFExportFormatOptions outputOptions = new PDFExportFormatOptions();
        ExportOptions exportOptions = new ExportOptions();
        exportOptions.setExportFormatType(ReportExportFormat.PDF);
        exportOptions.setFormatOptions(outputOptions);

        InputStream stream = doc.getPrintOutputController().export(
                exportOptions);
        byte[] bytes = StreamUtils.getBytes(stream);

        FileUtils.writeByteArrayToFile(new File("C:\\dev\\reports\\pdf\\Infomix_MultipleTables001.pdf"), bytes);

    }catch (Exception ex) {
        System.out.println(ex);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...