Ok, bạn vừa viết xong procedure hoặc function đầu tiên, chạy thử nó, nhưng có gì đó không ổn. Tất nhiên, bạn có thể thêm một đống RAISE NOTICE để xem "con tàu mắc cạn ở đâu". Nhưng mà! Sao phải khổ vậy khi pgAdmin có sẵn debugger cực xịn?
pgAdmin cho phép bạn chạy code từng bước, đặt breakpoint (điểm dừng), xem giá trị biến và tìm nguyên nhân lỗi. Nó đúng kiểu "bộ dụng cụ thám tử" để điều tra bí ẩn: "Tại sao truy vấn của mình không chạy?".
Tại sao nên debug bằng pgAdmin?
Đôi khi bug trong procedure ẩn sâu đến mức chỉ xem log hoặc text trên terminal thì đúng là cực hình. Lúc này, debug từng bước sẽ cứu bạn, vì bạn thấy được mọi thứ xảy ra ở từng bước thực thi function. Hãy tưởng tượng như bạn đang ráp một cái puzzle siêu khó mà lại có gợi ý.
Với debug trong pgAdmin, bạn có thể:
- Đặt breakpoint — là chỗ code sẽ dừng lại để bạn phân tích trạng thái hiện tại.
- Đi từng bước qua code SQL — đúng nghĩa từng bước xem lệnh nào đang chạy.
- Xem giá trị biến realtime — đảm bảo dữ liệu truyền và xử lý đúng.
- Tìm chỗ phát sinh lỗi và hiểu nguyên nhân của nó.
Bắt đầu: chuẩn bị debug trong pgAdmin
Trước khi debug, hãy chắc chắn mọi thứ đã setup chuẩn nhé.
Bật extension plpgsql
Đảm bảo database của bạn đã bật ngôn ngữ lập trình PL/pgSQL:
CREATE EXTENSION IF NOT EXISTS plpgsql;
Ngôn ngữ này thường được bật sẵn trong PostgreSQL, nhưng kiểm tra lại cho chắc.
Đảm bảo bạn đã cài pgAdmin bản 4 trở lên (mới hỗ trợ debug). Nếu chưa có, bạn có thể tải pgAdmin từ trang chính thức.
Cài extension pldbgapi
Để bật debug PL/pgSQL trong pgAdmin, bạn cần kích hoạt extension pldbgapi:
CREATE EXTENSION IF NOT EXISTS pldbgapi;
Extension này được thiết kế riêng để làm việc với debugger.
Rất quan trọng!!! Hãy chắc chắn bạn có quyền admin trên server PostgreSQL để chạy lệnh này.
Cơ bản về debug: đặt breakpoint
Breakpoint — là chỗ đặc biệt trong code, nơi procedure hoặc function sẽ dừng lại để bạn có thể "soi" bên trong. Nó giống như nghỉ giữa đường: dừng lại, nhìn quanh, kiểm tra bản đồ rồi đi tiếp.
Cách đặt breakpoint trong pgAdmin?
- Mở pgAdmin và kết nối tới database của bạn.
- Tìm function hoặc procedure của bạn trong cây object: Functions → <schema của bạn> → <function của bạn>.
- Click chuột phải vào function và chọn Debugging → Debug. Debugger sẽ bật lên.
- Trong cửa sổ code function, tìm dòng bạn muốn bắt đầu debug và click vào lề trái của dòng đó. Sẽ hiện ra một chấm đỏ — đó chính là breakpoint.
Ví dụ minh họa:
CREATE OR REPLACE FUNCTION example_function(id INTEGER)
RETURNS VOID AS $$
BEGIN
RAISE NOTICE 'Bạn đã chọn id: %', id;
-- Ở đây có thể đặt breakpoint
PERFORM some_operation(id);
END;
$$ LANGUAGE plpgsql;
Sau khi đặt breakpoint, bạn chạy function, và nó sẽ dừng đúng chỗ đó. Giờ bạn có thể kiểm tra giá trị biến, kết quả các lệnh trước đó và tất nhiên, tiếp tục chạy code.
Xem biến trong pgAdmin
Biết code dừng lại là tốt rồi. Nhưng còn tuyệt hơn nếu biết lúc đó trong bộ nhớ có gì. Ví dụ:
- Tham số đầu vào có giá trị gì.
- Biến thay đổi thế nào sau khi chạy một block.
- Query trả về gì cho database.
Làm sao xem giá trị biến?
Khi function dừng ở breakpoint:
- Chuyển sang tab Variables ở dưới cửa sổ debug.
- Bạn sẽ thấy danh sách tất cả biến và giá trị hiện tại của chúng.
Giả sử bạn có function như sau:
CREATE OR REPLACE FUNCTION calculate_discount(price NUMERIC, discount NUMERIC)
RETURNS NUMERIC AS $$
DECLARE
discounted_price NUMERIC;
BEGIN
discounted_price := price - (price * discount / 100);
RETURN discounted_price;
END;
$$ LANGUAGE plpgsql;
Nếu bạn đặt breakpoint ở dòng discounted_price, debugger sẽ cho thấy biến price và discount đã có giá trị, còn discounted_price thì vẫn rỗng.
Danh sách biến sau khi dừng sẽ như sau:
| Biến | Giá trị |
|---|---|
price |
100.00 |
discount |
15.00 |
discounted_price |
NULL |
Sau khi bạn chạy xong dòng hiện tại, discounted_price sẽ thành 85.00.
Chạy code từng bước
Trong cửa sổ debugger, bạn có thể điều khiển việc chạy function bằng các nút:
- Step Over — chạy xong lệnh hiện tại rồi chuyển sang lệnh tiếp theo.
- Step Into — "chui vào" function hoặc procedure được gọi.
- Continue — tiếp tục chạy tới breakpoint tiếp theo hoặc tới khi xong.
Thực hành: debug function phức tạp
Thử viết và debug một function phức tạp hơn nhé.
Ví dụ: xử lý đơn hàng
CREATE OR REPLACE FUNCTION process_order(order_id INTEGER)
RETURNS TEXT AS $$
DECLARE
order_status TEXT;
total_amount NUMERIC;
BEGIN
-- Đặt trạng thái đơn hàng
SELECT status INTO order_status
FROM orders
WHERE id = order_id;
IF order_status = 'Pending' THEN
-- Tính tổng tiền đơn hàng
SELECT SUM(price * quantity) INTO total_amount
FROM order_items
WHERE order_id = order_id;
-- Cập nhật trạng thái đơn hàng
UPDATE orders
SET status = 'Processed', processed_date = NOW()
WHERE id = order_id;
RETURN 'Đơn hàng đã xử lý. Tổng tiền: ' || total_amount;
ELSE
RETURN 'Đơn hàng đã xử lý hoặc không tồn tại.';
END IF;
END;
$$ LANGUAGE plpgsql;
Các breakpoint có thể đặt:
- Ở dòng
SELECT status INTO order_status. - Ở dòng
SELECT SUM(price * quantity) INTO total_amount.
Khi debug, bạn có thể:
- Đảm bảo
order_statusthực sự là'Pending'. - Kiểm tra
total_amounttính đúng chưa.
Lỗi thường gặp và cách xử lý
Khi debug bằng pgAdmin, bạn có thể gặp các tình huống sau:
- Không thấy function trong danh sách. Đảm bảo function đã được tạo trong database và bạn đang kết nối đúng database.
Breakpoint không hoạt động. Kiểm tra extension
pldbgapiđã bật và bạn có đủ quyền chưa.Lỗi kết nối debugger. Đảm bảo server PostgreSQL đã cấu hình cho debug (tham số
shared_preload_librariescópldbgapi).
Dùng pgAdmin để debug PL/pgSQL làm cho việc debug cực kỳ đơn giản và trực quan. Đặt breakpoint, xem biến đang "thở" thế nào, sửa hết lỗi — vậy là bạn đã đi được nửa đường tới ứng dụng hoàn hảo rồi đó!
GO TO FULL VERSION