ОШИБКА: неиспользуемая строка с титром или рядом

Выполняя приведенный ниже код запуска с использованием ANT, я получаю ошибку

org.postgresql.util.PSQLException: ERROR: unterminated quoted string at or near "' DECLARE timeout integer" Position: 57 

Я могу успешно выполнить приведенный ниже код через PGADmin (предоставляется postgres) и утилитой командной строки «psql», а функция триггера добавлена, но при выполнении через ANT она терпит неудачу каждый раз

 BEGIN TRANSACTION; CREATE OR REPLACE FUNCTION sweeper() RETURNS trigger as ' DECLARE timeout integer; BEGIN timeout = 30 * 24 * 60 * 60 ; DELETE FROM diagnosticdata WHERE current_timestamp - teststarttime > (timeout * ''1 sec''::interval); return NEW; END; ' LANGUAGE 'plpgsql'; -- Trigger: sweep on diagnosticdata CREATE TRIGGER sweep AFTER INSERT ON diagnosticdata FOR EACH ROW EXECUTE PROCEDURE sweeper(); END; 

Я столкнулся с этой ошибкой в Liquibase, и эта страница была одним из первых результатов поиска, поэтому, я думаю, я делюсь своим решением на этой странице:

Вы можете поместить весь свой sql в отдельный файл и включить его в набор изменений. Важно установить для параметра splitStatements значение false .

Тогда весь набор изменений будет выглядеть так:

    

Мне всегда нравятся большие SQL-части (например, обновления функций и т. Д.) В отдельных файлах. Таким образом, вы получаете правильное выделение синтаксиса при открытии файла sql и не должны смешивать XML и SQL в одном файле.


Изменить : как упоминалось в комментариях, стоит отметить, что изменение sql поддерживает также параметр splitStatements (thx to AndreyT для указания этого).

У меня была та же проблема с драйвером JDBC, используемым Liquibase.

Кажется, что драйвер взрывает каждую строку, заканчивающуюся точкой с запятой, и запускает ее как отдельную команду SQL. Вот почему приведенный ниже код будет выполняться драйвером JDBC в следующей последовательности:

  1. CREATE OR REPLACE FUNCTION test(text) RETURNS VOID AS ' DECLARE tmp text
  2. BEGIN tmp := "test"
  3. END;
  4. ' LANGUAGE plpgsql

Конечно, это недопустимый SQL и вызывает следующую ошибку:

 unterminated dollar-quoted string at or near ' DECLARE tmp text 

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

 CREATE OR REPLACE FUNCTION test(text) RETURNS void AS ' DECLARE tmp text; \ BEGIN tmp := "test"; \ END;' LANGUAGE plpgsql; 

В качестве альтернативы вы можете поместить все определение в одну строку.

Я использую клиент HeidiSQL, и это было решено, поставив DELIMITER // перед оператором CREATE OR REPLACE. В HeidiSQL есть также опция «Отправить пакет за один раз», которая по сути достигает того же.

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

Следующий код будет работать без потерь в Netbeans 7, Squirrel, DbSchema, PgAdmin3

 CREATE OR REPLACE FUNCTION author.revision_number() RETURNS trigger AS $BODY$ begin new.rev := new.rev + 1; new.revised := current_timestamp; return new; end; $BODY$ LANGUAGE plpgsql VOLATILE COST 100; 

Обратите внимание, что инструкция «begin» появляется сразу же после строки «$».

Следующий код остановит все вышеперечисленные клиенты, кроме PgAdmin3.

 CREATE OR REPLACE FUNCTION author.word_count() RETURNS trigger AS $BODY$ declare wordcount integer := 0; -- counter for words indexer integer := 1; -- position in the whole string charac char(1); -- the first character of the word prevcharac char(1); begin while indexer <= length(new.blab) loop charac := substring(new.blab,indexer,1); -- first character of string if indexer = 1 then prevcharac := ' '; -- absolute start of counting else prevcharac := substring(new.blab, indexer - 1, 1); -- indexer has increased end if; if prevcharac = ' ' and charac != ' ' then wordcount := wordcount + 1; end if; indexer := indexer + 1; end loop; new.words := wordcount; return new; end; $BODY$ LANGUAGE plpgsql VOLATILE COST 100; 

Важнейшим отличием во втором примере является раздел «объявление». Уловка использования обратных слешков вызывает ошибку с PgAdmin3.

В итоге я предлагаю попробовать различные инструменты. Некоторые инструменты, даже если они должны писать текстовые файлы, помещают в текст невидимые вещи. Как известно, это происходит с спецификацией Unicode, которая остановит любой php-файл, который пытается реализовать сеансы или пространства имен. Хотя это не решение, я надеюсь, что это поможет.

У меня была такая же проблема с zeos и c ++ builder. Решение в моем случае:
Измените разделитель свойств (обычно «;») на другой в компоненте (classе), который я использовал.

 dm->ZSQLProcessor1->DelimiterType=sdGo; 

Возможно, у Ant есть нечто похожее.

Этот пример работал для меня с PostgreSQL 14.1 и HeidiSQL 9.4.0.5125

 DROP TABLE IF EXISTS emp; CREATE TABLE emp ( empname text NOT NULL, salary integer ); DROP TABLE IF EXISTS EMP_AUDIT; CREATE TABLE emp_audit( operation char(1) NOT NULL, stamp timestamp NOT NULL, userid text NOT NULL, empname text NOT NULL, salary integer ); DELIMITER // CREATE OR REPLACE FUNCTION process_emp_audit() RETURNS TRIGGER AS $$ BEGIN -- -- Create a row in emp_audit to reflect the operation performed on emp, -- make use of the special variable TG_OP to work out the operation. -- IF (TG_OP = 'DELETE') THEN INSERT INTO emp_audit SELECT 'D', now(), user, OLD.*; RETURN OLD; ELSIF (TG_OP = 'UPDATE') THEN INSERT INTO emp_audit SELECT 'U', now(), user, NEW.*; RETURN NEW; ELSIF (TG_OP = 'INSERT') THEN INSERT INTO emp_audit SELECT 'I', now(), user, NEW.*; RETURN NEW; END IF; RETURN NULL; -- result is ignored since this is an AFTER trigger END; $$ LANGUAGE plpgsql; DROP TRIGGER IF EXISTS emp_audit ON emp; CREATE TRIGGER emp_audit AFTER INSERT OR UPDATE OR DELETE ON emp FOR EACH ROW EXECUTE PROCEDURE process_emp_audit(); 

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

 WHERE colA is NULL ; 

Убедитесь, что они находятся в одной строке, так как

 WHERE colA is NULL; 

Я знаю, что этот вопрос был задан давно, но у меня была такая же проблема с сценарием Postgresql (работа с Jenkins) с использованием SQL-задачи Ant.

Я попытался запустить этот SQL (сохраненный в файле с именем audit.sql):

 DROP SCHEMA IF EXISTS audit CASCADE ; CREATE SCHEMA IF NOT EXISTS audit AUTHORIZATION faktum ; CREATE FUNCTION audit.extract_interval_trigger () RETURNS trigger AS $extractintervaltrigger$ BEGIN NEW."last_change_ts" := current_timestamp; NEW."last_change_by" := current_user; RETURN NEW; END; $extractintervaltrigger$ LANGUAGE plpgsql ; 

но получил ошибку “unterminated knot-quoted string”. Нет проблем с запуском pgAdmin.

Я узнал, что это не драйвер, который разбивает скрипт на каждом “;” а скорее Ant.

На http://grokbase.com/t/postgresql/pgsql-jdbc/06cjx3s3y0/ant-sql-tag-for-dollar-quoting я нашел ответ:

Ant ест double – $$ как часть своей переменной обработки. Вы должны использовать $ BODY $ (или подобное) в сохраненных procs и поместить разделитель в свою собственную строку (с delimitertype = “row”). Тогда Ant будет сотрудничать.

Мой скрипт Ant SQL выглядит так: он работает:

  
Interesting Posts

Почему мы не должны использовать защищенный static в java

Запретить Windows изменять размер всех приложений на рабочем столе при переключении мониторов

«Не может прочитать заголовок Linux». Новая установка, старая машина

Есть ли способ, с помощью которого программа C / C ++ может сбой перед main ()?

Когда я использую точку, стрелку или двойную двоеточие, чтобы ссылаться на членов classа на C ++?

Подмножество кадра данных между двумя датами

Как получить группу переключающих кнопок, которые будут действовать как переключатели в WPF?

Пользовательская авторизация в Asp.net WebApi – какой беспорядок?

CSS-анимация с задержкой для каждого дочернего элемента

Как настроить цвет и текст режима действия?

Утечка памяти с настраиваемым шрифтом для настраиваемого шрифта

Можно ли «привязать» верх / низ вместо левого / правого в Windows 7?

Устаревший заголовок

Преобразование строки, совместимой с ISO 8601, в java.util.Date

Почему у меня нет права на создание текстового файла в корневом каталоге?

Давайте будем гением компьютера.