Проверка на синтаксиса на PostgreSQL без изпълнение на заявката

Искам да проверя синтаксиса на файловете, съдържащи sql заявки, преди да могат да бъдат ангажирани в моя CVS проект.

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

Скриптовете може да съдържат множество заявки, така че EXPLAIN не може да бъде обвито около тях.

Някакви съвети?


person RobAu    schedule 25.11.2011    source източник
comment
имам свързан проблем със SP на postgresql блок, който не е валидиран, докато не бъде извикан   -  person triclosan    schedule 25.11.2011
comment
@triclosan: може да се интересувате от plpgsql lint, който адресира точно този недостатък. Pavel Stěhule е главният разработчик. Вижте тази публикация в блог.   -  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
@докато се обзалагам, че няма да е трудно да го добавите към syntastic. Никога не съм използвал syntastic и нямам 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 изрази, които ще генерират грешки в зависимост от състоянието на db. също транзакциите работят на 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

Обикновено използвам Mimer онлайн SQL валидатор, единственото нещо е, че проверява SQL синтаксиса за стандартен SQL:

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

и не е специфично за PostgreSQL ... Въпреки това, ако пишете код, следвайки стандарта, можете да го използвате и той работи добре ...

person aleroot    schedule 25.11.2011
comment
Предимството да направите това е, че улеснявате превключването на бази данни. Обичам postgres и той е по-добър през последните години, но дълго време основната му философия изглеждаше Стандарти? Там, където отиваме, нямаме нужда от стандарти. - 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
Можете ли просто да изпълните множество изрази за избор? Или можете да използвате блокове 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 в среда за настройка, да изпълните определени функции и заявки, след което да излезете с 'RAISE EXCEPTION'. опитайте с Google за някакъв pgunit. Те използват такава техника - person shcherbak; 10.03.2017