2

アプリケーションのデータベース インストール スクリプトのさらに下で使用するために、Oracle でいくつかの変数を定義する必要があります。基本的に、現在のインストーラーの動作は、スクリプト ファイルを読み込み、Java の JDBC 経由でそれぞれを呼び出すというものです。それらを参照する必要があるプロシージャ、トリガー、作成ステートメントなどがあるため、データベース側でOracleに変数置換を実行させる必要があります(「CREATE TABLE &&MYSCHEMA.TBL_NAME ...」のように)。

私が抱えている問題は、DEFINE ステートメントを Java から呼び出すときにエラーがスローされることです (例)。

private static void testDefineVariables() {
    String url = "jdbc:oracle:thin:@localhost:1521:LOCALDEV";
    String username = "SYSTEM";
    String password = "manager42";
    Connection conn = null;
    Statement stmt = null;
    try {
        conn = DriverManager.getConnection(url, username, password);
        stmt = conn.createStatement();

        //Execute the sql
        stmt.execute("DEFINE MYSCHEMA='TESTSCHEMA'");

    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    finally {
        try {

        if(stmt != null)
            stmt.close();

        if(conn != null)
            conn.close();

        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

エラーは次のとおりです。

java.sql.SQLSyntaxErrorException: ORA-00900: invalid SQL statement

at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:439)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:395)
at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:802)
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:436)
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:186)
at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:521)
at oracle.jdbc.driver.T4CStatement.doOall8(T4CStatement.java:194)
at oracle.jdbc.driver.T4CStatement.executeForRows(T4CStatement.java:1000)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1307)
at oracle.jdbc.driver.OracleStatement.executeInternal(OracleStatement.java:1882)
at oracle.jdbc.driver.OracleStatement.execute(OracleStatement.java:1847)
at oracle.jdbc.driver.OracleStatementWrapper.execute(OracleStatementWrapper.java:301)

ojdbc6-11.2.0.1.0.jar JDBC ドライバーで Oracle 11g R2 データベースを使用しています。sqldeveloper ツールと SQLPlus コンソールからステートメントを正常に実行できますが、Java アプリケーションからは実行できません。データベース ドライバーで追加のプロパティを構成する必要がありますか? このドライバーからこの種の電話をかけることはできますか?

Java側で変数バインディングを使用することをすぐに提案する人がいるかもしれませんが、これはオプションではありません。スクリプトは、SQL インターフェースとインストーラーの両方から実行可能である必要があります。これ以外にも理由はありますが、ここでは触れません。

また、これを sql-maven-plugin で動作させることを望んでいますが、この JIRA に基づいてそれができない場合があります。

置換変数用の Oracle SQLPlus 構文を追加する

誰かが提案を持っているか、これを機能させる方法を知っているなら、私はそれを大いに感謝します.

4

2 に答える 2

6

DEFINE は SQLPLUS 以外では機能しないと思います。JAVA は JDBC を使用し、execute() の引数が有効な SQL であると想定しています。SQLPLUS 以外で DEFINE を使用できる場合は、使用しているユーティリティが SQLPLUS と互換性があるか、SQLPLUS の一部を置き換えることを意図していることを意味します。

DEFINE は SQLPLUS コマンドです。SQLPLUS は ORACLE ユーティリティです。

この URL によると、定義は SQL ステートメントではありません

http://www.adp-gmbh.ch/ora/sqlplus/define.html

于 2012-07-09T20:42:30.220 に答える
4

DEFINEと置換変数の構文はどちら&&MYSCHEMA.TBL_NAMEも SQL*Plus コマンドです。これらは、有効な SQL または PL/SQL 構成体ではありません。JDBC 経由でそのまま使用することはできません。

入りたくない理由によっては

  • Java アプリケーションは、オペレーティング システムを呼び出して SQL*Plus を呼び出し、スクリプトを渡すことができます。
  • Java アプリケーションは、スクリプトが依存する SQL*Plus 機能を実装できます。アプリケーションは、 を実行するのではなく 、変数 likeを値 like にマップするDEFINE MYSCHEMA='TESTSCHEMA'、たとえば を維持する必要があります。次に、アプリケーションは、 のようなテキストを探して個々の SQL ステートメントを解析し、それをローカルの値に置き換えて、結果の SQL 文字列をデータベース サーバーに送信する必要があります。レプリケートする必要がある SQL*Plus 機能の量によっては、かなりの作業になる可能性があります。多くの PL/SQL IDE (Toad や SQL Developer など) は、SQL*Plus の機能のサブセットを実装しています。SQL*Plus の機能をすべて実装しようとしたものは知りません。HashMapmyschemaTESTSCHEMA&&MYSCHEMAHashMap
于 2012-07-09T20:49:00.383 に答える