2013-08-20 35 views
6

Tôi đang so sánh về PostgreSQL và SQLServer cho mục đích di chuyển. Bây giờ tôi đang đánh giá T-SQL vs PL/pgSQL, điều này là trong T-SQL bạn có thể sử dụng vòng lặp hoặc khai báo các biến, ví dụ:PostgreSQL lặp lại các chức năng bên ngoài. Điều đó có thể không?

declare @counter int 
set @counter = 0 
while @counter < 10 
begin 
    set @counter = @counter + 1 
    print 'The counter is ' + cast(@counter as char) 
end 

Không cần phải đặt nó bên trong một hàm hoặc thủ tục. Tôi có thể làm điều đó trong PostgreSQL không?

Tìm kiếm trên web Tôi tìm thấy một số negative answer thực hiện trong MySQL nhưng tôi không tìm thấy câu trả lời như vậy cho Postgres.

Trả lời

15

Bạn không thểDECLARE (toàn cầu) biến (well, there are ways around this) cũng không vòng lặp với SQL đơn giản - với ngoại lệ của recursive CTEs as provided by @bma.

Tuy nhiên, có DO statement cho mã thủ tục ngoại tuyến như vậy. Được giới thiệu với Postgres 9.0. Nó hoạt động giống như hàm một lần, nhưng không trả về bất cứ thứ gì. Bạn có thể thông báo RAISE et al, vì vậy ví dụ của bạn sẽ chỉ làm việc tốt:

DO 
$do$ 
DECLARE 
    _counter int := 0; 
BEGIN 
    WHILE _counter < 10 
    LOOP 
     _counter := _counter + 1; 
     RAISE NOTICE 'The counter is %', _counter; -- coerced to text automatically 
    END LOOP; 
END 
$do$ 

Nếu không có quy định khác, ngôn ngữ cơ thể là plpgsql. Tuy nhiên, bạn có thể sử dụng any registered procedural language, nếu bạn khai báo (như: LANGUAGE plpython).

Postgres cũng cung cấp generate_series() để tạo tập hợp đặc biệt, điều này có thể làm giảm nhu cầu lặp trong nhiều trường hợp. Try a search here on SO for examples.

Ngoài ra, bạn có thể sử dụng WHERE điều khoản trong một data-modifying CTE trong SQL đơn giản đến ngã ba trường hợp và mô phỏng IF .. THEN .. ELSE .. END ...

+0

Awesome Trả lời! !! Cảm ơn! – JGutierrezC

+1

Nó đáng nhắc lại mạnh mẽ hơn ** nếu bạn có thể truyền lại vấn đề của mình dưới dạng vòng lặp, hãy làm như vậy ** - nghĩa là, nếu bạn có thể xây dựng truy vấn SQL hoạt động trên kết quả trong một lần, có khả năng hoạt động tốt hơn nhiều so với việc sử dụng mã thủ tục. – IMSoP

3

Bạn có thể truy vấn đệ quy các tập kết quả bằng cách sử dụng VỚI NHẬN, giả sử bạn đang sử dụng Postgresql 8.4+. Tài liệu: http://www.postgresql.org/docs/current/static/queries-with.html

Điều này sẽ cho phép bạn lặp lại bộ và xử lý dữ liệu theo nhiều cách khác nhau.

+0

Cảm ơn bạn rất nhiều BMA. Nhưng tôi có thể sử dụng từ khóa Declare không? bởi vì đôi khi bạn cần phải chèn ví dụ, hoặc tùy thuộc vào một số contidition nếu điều kiện là đúng chèn khác nếu ... cập nhật ... khác xóa ... tôi rõ ràng? Trân trọng. – JGutierrezC

+2

"Khai báo", không, nhưng sử dụng mệnh đề WITH, bạn có thể gửi một giá trị trong một trong các điều khoản trên cùng và tham chiếu nhiều lần trong các vị trí tiếp theo của truy vấn (còn được gọi là "chuỗi"). Ví dụ: trong liên kết tôi đã cung cấp, phần "region_sales" được sử dụng làm nguồn cho phần tiếp theo (có tên là "top_regions"). Điều đó minh họa chuỗi truy vấn tôi đã đề cập. Trong Postgresql 9.2+, bạn có thể sử dụng mệnh đề WITH (aka "Express Table Expressions" (CTE)) để làm "upsert" báo cáo (mà bạn gọi là "chèn inf đúng, khác cập nhật, khác xóa") – bma

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