質問

現在、アプリケーション用のテスト環境を設定しています。テスト環境でJunitとSpringを使用しています。テスト実行の前に、データベーステスト環境状態を設定したいと思います。私はすでにSQLスクリプト(スキーマとデータ)を書いており、それらはOracles SQLDEVELOPTERで正常に実行されています。 Oracle Thin JDBCドライバーを使用してそれらを実行しようとしたとき、実行は失敗します。薄いドライバーは、トリガーステートメントを作成するのが好きではないようです。

薄いドライバーの代わりにOCIドライバーを使用する必要があることを読みました。 OCIドライバーの問題は、プラットフォームが独立しておらず、セットアップに時間がかかることです。

私のコードの例:

CREATE TABLE "USER"
  (
    USER_ID          NUMBER(10) NOT NULL,
    CREATOR_USER_FK  NUMBER(10) NOT NULL,
    ...
    PRIMARY KEY (USER_ID)
  );
CREATE SEQUENCE SEQ_USER START WITH 1 INCREMENT BY 1;
CREATE TRIGGER "USER_ID_SEQ_INC" BEFORE
  INSERT ON "USER" FOR EACH ROW BEGIN
  SELECT SEQ_USER.nextval
  INTO :new.USER_ID
  FROM DUAL;
END;

トリガーステートメントを実行すると、実行は失敗しますが、クエリの最初の部分( "user_id_seq_inc" ... "user" ... begin from dual;)の最初の部分は正常に実行されますが、私がそれを使用しようとすると、トリガーは破損しているようです。実行障害エラーは、ステートメントの終了の2番目の部分に伴います。 「ORA-00900:無効なSQLステートメント」。

誰かがその問題の解決策を知っていますか?プラットフォームに依存しない薄いJDBCドライバーを使用してトリガーを作成したいだけです。

乾杯!

ケビン

役に立ちましたか?

解決

答えてくれてありがとう、それは今正常に機能します。その理由は、Spring FrameForkを使用したSQLコードファイルの構文ミスまたは解釈でした。 JDBCの実行方法を使用してステートメントを直接実行すると、Spring機能を使用してスクリプト実行に使用すると、実行が失敗します。 Oracle SQLコードでは、HSQLDB SQLコードを使用すると正常に動作するため、注意が必要です。

test-condext.xml:

...
<jdbc:initialize-database data-source="dataSource"
    ignore-failures="DROPS" enabled="${jdbc.enableSqlScripts}">
    <jdbc:script location="${jdbc.initLocation}" />
    <jdbc:script location="${jdbc.dataLocation}" />
</jdbc:initialize-database>
...

schema.sql:

DROP SEQUENCE SEQ_USER;
DROP TABLE "USER" CASCADE CONSTRAINTS;
PURGE TABLE "USER";
CREATE TABLE "USER"
  (
    USER_ID          NUMBER(10) NOT NULL,
    CREATOR_USER_FK  NUMBER(10) NOT NULL,
    PRIMARY KEY (USER_ID)
  );
ALTER TABLE "USER" ADD CONSTRAINT FK_USER_CUSER FOREIGN KEY (CREATOR_USER_FK) REFERENCES "USER" (USER_ID);
CREATE SEQUENCE SEQ_USER START WITH 1 INCREMENT BY 1;
CREATE TRIGGER "USER_ID_SEQ_INC" BEFORE
  INSERT ON "USER" FOR EACH ROW
  WHEN (new.USER_ID IS NULL)
BEGIN
  SELECT SEQ_USER.nextval
  INTO :new.USER_ID
  FROM DUAL;
END;
/
ALTER TRIGGER "USER_ID_SEQ_INC" ENABLE;

これは正常に機能します!削除することが重要です ; ステートメントの最後に、トリガーステートメントを除きます!!!

@Before
public void executeSomeSql() {
    Connection c;
    try {
        c = dataSource.getConnection();
        c.createStatement()
                .execute("CREATE TABLE \"USER\" (USER_ID NUMBER(10) NOT NULL, CREATOR_USER_FK NUMBER(10) NOT NULL, PRIMARY KEY (USER_ID))");
        c.createStatement()
                .execute("CREATE SEQUENCE SEQ_USER START WITH 1 INCREMENT BY 1");
        c.createStatement()
                .execute("CREATE OR REPLACE TRIGGER \"USER_ID_SEQ_INC\" BEFORE INSERT ON \"USER\" FOR EACH ROW WHEN (new.USER_ID IS NULL) BEGIN SELECT SEQ_USER.nextval INTO :new.USER_ID FROM DUAL; END;");
    } catch (SQLException e) {
        logger.debug(e);
    }
}

他のヒント

トリガーの作成は、あらゆるタイプのJDBCドライバーで動作します。 SQL構文には何か問題があるに違いありません - これは、Oracleが実行されたときに報告する必要があるため、奇妙です CREATE TRIGGER (初めて使用するときではありません)。

使用しているので BEGIN ... END; あなたが本当に持っていることを確認してください ;END DBに送信するSQLで。

それが原因でない場合、 この記事を確認してください.

私はこれが古い投稿であることを知っていますが、ここに私の答えがあります。

デフォルトでは、spring "Initialize-database"命令semicolon文字: ";"を使用して指定されたスクリプトを分割します。

トリガーでは、トリガー内にセミコロンがあることが多いため、クエリがひどく分割されて実行されます。

解決策は、このような別の分割文字( "|")を使用することです。

<jdbc:initialize-database>
    <jdbc:script location="classpath:myscript.sql" separator="|"/>
</jdbc:initialize-database>
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top