2011-11-25 36 views
25

Tôi muốn xác minh cú pháp của các tệp có chứa truy vấn sql trước khi chúng có thể được cam kết trong dự án CVS của tôi.kiểm tra cú pháp postgresql mà không cần chạy truy vấn

Để làm điều đó, tôi có một tập lệnh cam kết, nhưng tôi gặp khó khăn trong việc tìm hiểu xem các lệnh sql có hợp lệ hay không. psql dường như không có một chế độ dryrun, và xây dựng của riêng tôi postgresql-dialact thử nghiệm từ ngữ pháp (có nghĩa là trong nguồn) có vẻ như một đoạn dài.

Các tập lệnh có thể chứa nhiều truy vấn, do đó, không thể quấn xung quanh chúng EXPLAIN.

Bất kỳ gợi ý nào?

+0

tôi đã liên quan đến vấn đề với SP trên khối postgresql không xác nhận cho đến khi không được gọi – triclosan

+7

@triclosan của nó: bạn có thể quan tâm trong ['plpgsql lint'] (https://github.com/okbob/plpgsql_lint) giải quyết chính xác sự thiếu sót này. Pavel Stěhule là nhà phát triển chính. Xem [bài đăng blog] này (http://okbob.blogspot.com/2011/07/plpgsql-lint.html). –

+0

Tôi không có kinh nghiệm với postgres vì ​​vậy đây có lẽ là một giải pháp xấu không xứng đáng với một câu trả lời thực sự, nhưng tôi chỉ thêm một dòng rác ở cuối kịch bản mà tôi biết sẽ gây ra lỗi. Nếu lỗi đầu tiên nó chạm là dòng rác, tôi có thể tự tin hợp lý phần còn lại của tập lệnh là ok. Không giống như một giao dịch, nó bảo tồn các giá trị chuỗi và cho các kịch bản đơn giản, nó nhanh hơn và dễ dàng hơn việc tải xuống một tiện ích khác. –

Trả lời

33

Gần đây tôi đã viết một tiện ích để kiểm tra cú pháp của SQL cho PostgreSQL. Nó sử dụng ecpg, trình tiền xử lý SQL C nhúng cho các postgres, để kiểm tra cú pháp SQL, vì vậy nó sử dụng chính xác trình phân tích cú pháp tương tự được xây dựng trong chính Postgres.

Bạn có thể xem thử trên github: http://github.com/markdrago/pgsanity. Bạn có thể cung cấp cho README một skim để có được một ý tưởng tốt hơn về cách nó hoạt động và để nhận được hướng dẫn về cách cài đặt nó. Dưới đây là một ví dụ ngắn về cách pgsanity thể được sử dụng:

$ 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" 
+0

Điều đó có vẻ hữu ích. Tôi sẽ kiểm tra điều này sớm – RobAu

+3

Cảm ơn vì pgsanity! Nó thực sự tiện dụng. Có cách nào để sử dụng pgsanity trong systastic (https://github.com/scrooloose/syntastic)? Nó sẽ thực sự tuyệt vời để chạy kiểm tra tự động khi lưu tệp trong vim. – while

+0

@ trong khi tôi đặt cược nó sẽ không khó để thêm nó vào cú pháp. Tôi đã không bao giờ sử dụng cú pháp và tôi không có fim vim để thêm nó vào của riêng tôi. Nhưng kể từ khi pgsanity trả về một 0 trên thành công hoặc khác không về thất bại tôi đặt cược nó sẽ là tương đối dễ dàng để thêm. –

13

Một cách sẽ được đặt nó vào một giao dịch mà bạn quay trở lại ở cuối:

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

Hãy nhận biết rằng có một số hiệu ứng mà không thể được cuộn lại, giống như dblink cuộc gọi, hoặc bất cứ điều gì bằng văn bản cho hệ thống tập tin hoặc trình tự tăng dần.

Tôi khuyên bạn nên sao chép cơ sở dữ liệu của mình cho mục đích thử nghiệm.

+0

Chỉ có thể thực hiện thao tác này bằng kết nối đang hoạt động. Tôi muốn có một kiểm tra tĩnh. Và điều này sẽ không phá vỡ nếu tôi có các câu lệnh BEGIN trong sql của tôi? – RobAu

+0

@RobAu: Bổ sung 'BEGIN;' sẽ bị bỏ qua. Một 'CẢNH BÁO' sẽ được phát hành. –

+1

@RobAu: kiểm tra tĩnh sẽ không hoạt động với truy vấn động. Vâng: không phải lúc nào. Điều duy nhất bạn có thể làm là sandboxing và cầu nguyện. – wildplasser

6

Tôi thường sử dụng Mimer online SQL validator, điều duy nhất là nó kiểm tra cú pháp SQL cho SQL tiêu chuẩn:

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

và không cụ thể cho PostgreSQL ... Tuy nhiên nếu bạn viết mã theo tiêu chuẩn, bạn có thể sử dụng nó và nó hoạt động tốt ...

+0

Ưu điểm của việc này là bạn dễ dàng chuyển đổi cơ sở dữ liệu. Tôi yêu bưu chính, và nó đã được tốt hơn trong những năm gần đây, nhưng trong một thời gian dài triết lý cơ bản của nó dường như là "Tiêu chuẩn? Chúng ta đang đi đâu, chúng ta không cần tiêu chuẩn." – corsiKa

1

Bạn chỉ có thể bọc nó trong SELECT 1 (<your query>) AS a WHERE 1 = 0;

Nó sẽ thất bại trên xác nhận nhưng nó sẽ không thực sự thực thi. Dưới đây là một kế hoạch dụ truy vấn:

Result (cost=0.00..0.01 rows=1 width=0) 
    One-Time Filter: false 
+0

Làm cách nào để bọc nhiều câu lệnh sql trong một lựa chọn? – RobAu

+0

Bạn có thể chạy nhiều câu lệnh chọn không? Hoặc bạn có thể sử dụng VỚI khối lúc đầu. –

2

Một tiện ích tuyệt vời để kiểm tra cú pháp SQL: SQL Fiddle

Hỗ trợ MySQL, Oracle, PostgreSQL, SQLite, MS SQL.

5

GIẢI THÍCH (không có ANALYZE) sẽ phân tích cú pháp truy vấn và chuẩn bị kế hoạch thực thi mà không thực thi nó.

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

+0

Cảm ơn bạn đã dành thời gian viết câu trả lời, nhưng như tôi đã giải thích trong câu hỏi, tôi không thể sử dụng GIẢI THÍCH. – RobAu

0

Bạn có thể chạy truy vấn là chức năng postgresql và tăng ngoại lệ vào cuối. Tất cả thay đổi sẽ được khôi phục.Ví dụ:

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; 

Một sollution - plpgsql_check mở rộng (on github), sự tái sanh của pgpsql_lint

+0

cách này sẽ làm việc cho các kịch bản lệnh SQL nhiều câu lệnh? – RobAu

+0

bạn có thể viết một khoảng trống trả về bao bọc và bao gồm tất cả DML để thiết lập môi trường, chạy các chức năng và truy vấn cụ thể, sau đó thoát ra bằng 'RAISE EXCEPTION'. thử google cho một số loại pgunit. Họ sử dụng kỹ thuật đó – shcherbak

Các vấn đề liên quan