Проверка синтаксиса PostgreSQL без запуска запроса

Я хочу проверить синтаксис файлов, содержащих запросы sql, прежде чем их можно будет зафиксировать в моем проекте CVS.

Для этого у меня есть скрипт commitinfo, но мне трудно узнать, допустимы ли команды sql. psql, похоже, не имеет режима пробного запуска, и создание моего собственного тестера postgresql-diaact из грамматики (то есть в исходном коде) кажется долгим натяжением.

Скрипты могут содержать несколько запросов, поэтому вокруг них нельзя обернуть EXPLAIN.

Любые подсказки?


person RobAu    schedule 25.11.2011    source источник
comment
у меня есть связанная проблема с SP в блоке postgresql, не проверенном до тех пор, пока он не будет вызван   -  person triclosan    schedule 25.11.2011
comment
@triclosan: вас может заинтересовать plpgsql lint, который устраняет именно этот недостаток. Павел Стегуле — главный разработчик. См. этот сообщение в блоге.   -  person Erwin Brandstetter    schedule 25.11.2011
comment
Я не очень разбираюсь в postgres, так что это, вероятно, плохой обходной путь, не достойный реального ответа, но я просто добавляю мусорную строку в конец скрипта, которая, как я знаю, вызовет ошибку. Если первая ошибка, которую он выдает, это строка мусора, я могу быть достаточно уверен, что остальная часть скрипта в порядке. В отличие от транзакции он сохраняет значения последовательности, а для простых скриптов это быстрее и проще, чем скачивание другой утилиты.   -  person Ben Sutton    schedule 08.09.2016


Ответы (8)


Недавно я написал утилиту для статической проверки синтаксиса SQL для PostgreSQL. Он использует ecpg, встроенный препроцессор SQL C для Postgres, для проверки синтаксиса SQL, поэтому он использует тот же самый синтаксический анализатор, который встроен в сам Postgres.

Вы можете проверить это на github: http://github.com/markdrago/pgsanity. Вы можете просмотреть README, чтобы лучше понять, как он работает, и получить инструкции по его установке. Вот краткий пример того, как можно использовать pgsanity:

$ pgsanity good1.sql good2.sql bad.sql
bad.sql: line 1: ERROR: syntax error at or near "bogus_token"

$ find -name '*.sql' | xargs pgsanity
./sql/bad1.sql: line 59: ERROR: syntax error at or near ";"
./sql/bad2.sql: line 41: ERROR: syntax error at or near "insert"
./sql/bad3.sql: line 57: ERROR: syntax error at or near "update"
person Mark Drago    schedule 03.11.2012
comment
Это выглядит полезным. Я проверю это в ближайшее время - person RobAu; 03.11.2012
comment
Спасибо за пгсанити! Это очень удобно. Есть ли способ использовать pgsanity в systastic (github.com/scrooloose/syntastic)? Было бы действительно здорово запускать проверку автоматически при сохранении файла в vim. - person while; 21.05.2013
comment
@хотя держу пари, добавить его в синтаксический не составит труда. Я никогда не использовал синтаксис, и у меня нет vim foo, чтобы добавить его самостоятельно. Но поскольку pgsanity возвращает 0 в случае успеха или ненулевое значение в случае неудачи, держу пари, это будет относительно легко добавить. - person Mark Drago; 05.07.2013
comment
Отличный инструмент @MarkDrago спас меня после часов безуспешной отладки. :-) - person nelsonic; 30.03.2019
comment
Похоже, это больше не разрабатывается. Это правильно? - person LondonRob; 25.03.2021

Используйте этот прием для проверки синтаксиса кода PostgreSQL:

DO $SYNTAX_CHECK$ BEGIN RETURN;
    -- insert your SQL code here
END; $SYNTAX_CHECK$;

Функция is_sql(текст sql)

person Rinat    schedule 04.03.2020
comment
Этот трюк гениален! PostgreSQL проверит синтаксис всего кода SQL в блоке, но из-за RETURN в начале ни один из них фактически не выполняется. Хороший! - person Deven T. Corzine; 20.06.2020
comment
Принятый ответ хорош. Но это хорошо и непринужденно. - person Sy Tran; 12.10.2020
comment
Было бы неплохо узнать, что это за синтаксис. Это определение функции, верно? - person LondonRob; 25.03.2021

Одним из способов было бы поместить его в транзакцию, которую вы откатываете в конце:

BEGIN;
<query>;
<query>;
<query>;
ROLLBACK;

Имейте в виду, что некоторые эффекты нельзя отменить, например dblink. вызовы или что-либо, записанное в файловую систему или увеличенные последовательности.

Я бы посоветовал клонировать вашу базу данных для целей тестирования.

person Erwin Brandstetter    schedule 25.11.2011
comment
Это можно сделать только при активном соединении. Я бы предпочел иметь статическую проверку. И не сломается ли это, если у меня есть операторы BEGIN в моем sql? - person RobAu; 25.11.2011
comment
@RobAu: дополнительные BEGIN; будут игнорироваться. Будет выдан WARNING. - person Erwin Brandstetter; 25.11.2011
comment
@RobAu: статическая проверка не будет работать с динамическими запросами. Ну: не всегда. Единственное, что вы можете сделать, это сидеть в песочнице и молиться. - person wildplasser; 25.11.2011
comment
это действительно плохая идея. существует множество допустимых операторов sql, которые будут вызывать ошибки в зависимости от состояния базы данных. также транзакции работают с CRUD, но не с изменениями схемы, что также является SQL - person Sonic Soul; 19.06.2019

EXPLAIN (без ANALYZE) проанализирует запрос и подготовит план выполнения, фактически не выполняя его.

https://www.postgresql.org/docs/current/static/sql-explain.html

person karlgold    schedule 30.05.2016
comment
Спасибо, что нашли время написать ответ, но, как я уже объяснил в вопросе, я не могу использовать EXPLAIN. - person RobAu; 31.05.2016

Я обычно использую онлайн-валидатор SQL Mimer, единственное, что он проверяет синтаксис SQL для стандартного SQL:

  • SQL-92
  • SQL-99
  • SQL-03

и не специфично для PostgreSQL ... Однако, если вы пишете код в соответствии со стандартом, вы можете его использовать, и он работает хорошо ...

person aleroot    schedule 25.11.2011
comment
Преимущество этого заключается в том, что вы упрощаете переключение баз данных. Я люблю postgres, и в последние годы он стал лучше, но долгое время его основная философия казалась Standards? Там, куда мы идем, нам не нужны стандарты. - person corsiKa; 19.12.2015
comment
Недостатком является то, что если у вас есть имена таблиц или столбцов, которые имеют заглавные буквы и тому подобное, эти идентификаторы должны быть записаны в кавычках, что, я думаю, не является соглашением в других базах данных. - person OzzyTheGiant; 22.07.2020

Замечательная утилита для проверки синтаксиса SQL: SQL Fiddle.

Поддерживает MySQL, Oracle, PostgreSQL, SQLite, MS SQL.

person Anshul Tiwari    schedule 04.05.2016

Вы можете просто завернуть его в SELECT 1 ( <your query> ) AS a WHERE 1 = 0;

При проверке произойдет сбой, но на самом деле он не будет выполнен. Вот пример плана запроса:

Result  (cost=0.00..0.01 rows=1 width=0)
  One-Time Filter: false
person Jeff Wu    schedule 16.10.2015
comment
Как обернуть несколько операторов sql в один выбор? - person RobAu; 18.10.2015
comment
Можете ли вы просто запустить несколько операторов select? Или вы можете использовать блоки WITH в начале. - person Jeff Wu; 23.10.2015

Вы можете запускать запросы внутри функции postgresql и в конце вызывать исключение. Все изменения будут отменены. Например:

CREATE OR REPLACE FUNCTION run_test(_sp character varying)
  RETURNS character varying AS
$BODY$
BEGIN
  EXECUTE 'SELECT ' || _sp;
  RAISE EXCEPTION '#OK';
EXCEPTION
  WHEN others THEN
    RETURN SQLERRM;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;

Другое решение — расширение plpgsql_check (на github), следующее воплощение pgpsql_lint

person shcherbak    schedule 10.03.2017
comment
вы можете написать оболочку, возвращающую void, и включить все DML для настройки среды, запустить определенные функции и запросы, а затем выйти с помощью «ПОВЫШИТЬ ИСКЛЮЧЕНИЕ». поищите в гугле какой-нибудь pgunit. Они используют такую ​​технику - person shcherbak; 10.03.2017