Создайте триггер oracle db с помощью тонкого драйвера jdbc - PullRequest
4 голосов
/ 05 ноября 2010

В настоящее время я настраиваю тестовую среду для приложения. Я использую jUnit и Spring в моей тестовой среде. Перед выполнением теста я хочу настроить состояние тестовой среды базы данных. Я уже написал сценарии SQL (схема и данные), и они прекрасно работают в OracleDeveloper. Когда я попытался выполнить их с помощью драйвера jdbc oracle thin, выполнение завершилось неудачно. Похоже, что тонкий драйвер не любит создавать операторы триггера.

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

Пример моего кода:

<code>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;

Если я выполняю оператор триггера, выполнение завершается неудачно, но, похоже, первая часть запроса (CREATE TRIGGER "USER_ID_SEQ_INC" ... "USER" ... BEGIN ... FROM DUAL;) выполнена успешно, но триггер, кажется, поврежден, если я пытаюсь его использовать. Ошибка сбоя выполнения сопровождается второй частью инструкции END; «ORA-00900: недопустимый оператор SQL».

Кто-нибудь знает решение этой проблемы? Я просто хочу создать триггер с независимым от платформы тонким драйвером jdbc.

Ура! * * 1013

Кевин

Ответы [ 3 ]

2 голосов
/ 06 ноября 2010

Спасибо, ребята, за ваши ответы, теперь все отлично работает.Причиной была ошибка синтаксиса или интерпретация моего файла кода SQL с помощью Spring Framefork.Когда я выполняю операторы напрямую, используя метод execute jdbc, это работает, когда я использую функциональность Spring для выполнения скрипта, выполнение завершается неудачно.С SQL-кодом oracle это кажется сложным, потому что если я использую SQL-код hsqldb, он работает нормально.

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);
    }
}
1 голос
/ 10 апреля 2013

Я знаю, что это старый пост, но вот мой ответ.

По умолчанию инструкция Spring "initialize-database" разделяет указанный скрипт с помощью символа точки с запятой: ";".

В триггере часто есть точка с запятой внутри триггера, поэтому запросы плохо разбиты и выполнены.

Решение состоит в том, чтобы использовать другой разделенный символ (например, "|"):

<jdbc:initialize-database>
    <jdbc:script location="classpath:myscript.sql" separator="|"/>
</jdbc:initialize-database>
1 голос
/ 05 ноября 2010

Создание триггеров работает с любым типом драйвера JDBC; должно быть что-то не так с синтаксисом SQL - что странно, потому что Oracle должен сообщать об этом при запуске CREATE TRIGGER (а не при первом использовании).

Поскольку вы используете BEGIN ... END;, убедитесь, что у вас действительно есть ; после END в SQL, который вы отправляете в БД.

Если это не причина, проверьте эту статью .

...