Загрузить триггер SQL из файла в Spring Boot

Я пытаюсь загрузить настраиваемые триггеры базы данных из файла sql в папку ресурсов.

В моем тестовом классе я добавил эту аннотацию @Sql("classpath:custom_script.sql")

В этом файле у меня есть триггеры для базы данных PostgreSQL. Когда я выполняю эти сценарии из инструмента запросов PgAdmin, они работают нормально, но когда я загружаю его из предварительных тестов в приложении Spring Boot, я получаю следующую ошибку:

или вложенное исключение - org.postgresql.util.PSQLException: незавершенная долларовая котировка, начатая с позиции 64 в SQL. CREATE OR REPLACE FUNCTION MY_TRIGGER_PROC () RETURNS TRIGGER AS $ CUSTOM_TRG $ DECLARE FOO_V INTEGER. Ожидается прекращение работы $$

В custom_script.sql у меня есть три связанных триггера:

CREATE OR REPLACE FUNCTION MY_TRIGGER_PROC()
  RETURNS TRIGGER AS $CUSTOM_TRG$
DECLARE FOO_V INTEGER;
BEGIN
  SELECT COUNT(F.ID)
  INTO FOO_V
  FROM FOO_TABLE F;

  IF FOO_V > 0
  THEN
    RAISE EXCEPTION 'CUSTOM EXCEPTION ERROR MESSAGE FOR ID ', NEW.ID
    USING ERRCODE = 'restrict_violation';
  END IF;
  RETURN NEW;
END;
$CUSTOM_TRG$
LANGUAGE plpgsql;

CREATE TRIGGER CUSTOM_TRG
  BEFORE INSERT
  ON FOO_TABLE
  FOR EACH ROW
EXECUTE PROCEDURE MY_TRIGGER_PROC();

Я ожидал, что эта ошибка будет из-за проблемы с разделителем или несколькими строками, поэтому я добавляю эти свойства в файл свойств:

spring.jpa.properties.hibernate.connection.charSet=UTF-8
spring.jpa.properties.hibernate.hbm2ddl.import_files_sql_extractor=org.hibernate.tool.hbm2ddl.MultipleLinesSqlCommandExtractor
spring.datasource.separator=^;

а также отредактируйте мой скрипт, как вы можете видеть в коде ниже, но это не помогло. Вы можете мне с этим помочь? Спасибо.

Отредактированный сценарий:

CREATE OR REPLACE FUNCTION MY_TRIGGER_PROC()
  RETURNS TRIGGER AS $CUSTOM_TRG$
DECLARE FOO_V INTEGER;
BEGIN
  SELECT COUNT(F.ID)
  INTO FOO_V
  FROM FOO_TABLE F;

  IF FOO_V > 0
  THEN
    RAISE EXCEPTION 'CUSTOM EXCEPTION ERROR MESSAGE FOR ID ', NEW.ID
    USING ERRCODE = 'restrict_violation';
  END IF;
  RETURN NEW;
END;
$CUSTOM_TRG$
LANGUAGE plpgsql^;

CREATE TRIGGER CUSTOM_TRG
  BEFORE INSERT
  ON FOO_TABLE
  FOR EACH ROW
EXECUTE PROCEDURE MY_TRIGGER_PROC()^;

person Aligator    schedule 21.02.2018    source источник


Ответы (1)


Решение состоит в том, чтобы заключить определение функции в одинарные кавычки вместо $ CUSTOM_TRG $, как здесь используется; в подобных случаях следует снова отказаться от котировки в долларах США в пользу простых одинарных кавычек. Однако одинарные кавычки всего определения требуют экранирования кавычек внутри определения функции, как указано в документации Postgresql:

Часто бывает полезно использовать долларовые кавычки (см. Раздел 4.1.2.4) для записи строки определения функции вместо обычного синтаксиса одинарных кавычек. Без использования долларовых кавычек любые одинарные кавычки или обратные косые черты в определении функции должны быть экранированы путем их удвоения.

Итак, в вашем примере вам нужно будет удвоить одинарные кавычки в определении функции, что происходит в логике, где FOO_V> 0.

person Ben    schedule 04.09.2018