Làm thế nào để bạn gỡ lỗi các thủ tục lưu trữ MySQL?


125

Quy trình hiện tại của tôi để gỡ lỗi các thủ tục được lưu trữ rất đơn giản. Tôi tạo một bảng có tên "gỡ lỗi", nơi tôi chèn các giá trị biến từ thủ tục được lưu trữ khi nó chạy. Điều này cho phép tôi xem giá trị của bất kỳ biến nào tại một điểm nhất định trong tập lệnh, nhưng có cách nào tốt hơn để gỡ lỗi các thủ tục được lưu trữ MySQL không?


2
Có bất kỳ tùy chọn GUI nào cho người dùng không phải Windows không? Việc phải chạy một bản sao của Windows chỉ để gỡ lỗi các thủ tục được lưu trữ là một bước nhảy vọt. Và hầu hết các tùy chọn chèn bảng đều thất bại nếu bạn đang tham gia một giao dịch mà bạn sắp khôi phục.
Mã Abominator

Câu trả lời:


44

Tôi làm một cái gì đó rất giống với bạn.

Tôi thường bao gồm một thông số Gỡ bỏ mặc định là sai và tôi có thể đặt thành đúng tại thời điểm chạy. Sau đó, bọc các câu lệnh gỡ lỗi thành một khối "If DEBUG".

Tôi cũng sử dụng bảng ghi nhật ký với nhiều công việc của mình để tôi có thể xem xét các quy trình và thời gian. Mã gỡ lỗi của tôi cũng được xuất ở đó. Tôi bao gồm tên tham số đang gọi, mô tả ngắn gọn, số lượng hàng bị ảnh hưởng (nếu thích hợp), trường nhận xét và dấu thời gian.

Các công cụ gỡ lỗi tốt là một trong những thất bại đáng buồn của tất cả các nền tảng SQL.


3
Không phải tất cả các nền tảng @ Bob Probst, Sybase công cụ gỡ lỗi được yên tĩnh đàng hoàng với breakpoint gỡ lỗi thủ tục kích hoạt và lưu trữ
Anup

69

Quy debug_msgtrình sau có thể được gọi để chỉ xuất một thông báo gỡ lỗi tới bảng điều khiển:

DELIMITER $$

DROP PROCEDURE IF EXISTS `debug_msg`$$
DROP PROCEDURE IF EXISTS `test_procedure`$$

CREATE PROCEDURE debug_msg(enabled INTEGER, msg VARCHAR(255))
BEGIN
  IF enabled THEN
    select concat('** ', msg) AS '** DEBUG:';
  END IF;
END $$

CREATE PROCEDURE test_procedure(arg1 INTEGER, arg2 INTEGER)
BEGIN
  SET @enabled = TRUE;

  call debug_msg(@enabled, 'my first debug message');
  call debug_msg(@enabled, (select concat_ws('','arg1:', arg1)));
  call debug_msg(TRUE, 'This message always shows up');
  call debug_msg(FALSE, 'This message will never show up');
END $$

DELIMITER ;

Sau đó chạy thử nghiệm như sau:

CALL test_procedure(1,2)

Nó sẽ dẫn đến kết quả sau:

** DEBUG:
** my first debug message
** DEBUG:
** arg1:1
** DEBUG:
** This message always shows up

8
Điều này dường như không hiệu quả với FUNCTIONS và tôi không biết tại sao. Nó luôn cho "Mã lỗi: 1415. Không được phép trả về tập kết quả từ một hàm". Có bất kỳ truy đòi nào không?
Patrick M

1
@PatrickM Functions không thể trả về hàng ("kết quả") trong khi thủ tục gỡ lỗi này dựa vào nó (thông báo gỡ lỗi là tập kết quả được trả về trong lệnh gọi thủ tục). Trong chức năng, bạn chỉ có thể INSERT INTO my_log_table (message) VALUES (msg)và có thể lấy tất cả các thông điệp debug một lần gọi hàm hơn (ví dụ: bạn đang trở lại trong thủ tục)
Xenos

Aproach này rất tốt nhưng việc ghi vào bảng điều khiển không hiệu quả trên MySQL Workbench như IDE. bởi vì mọi câu lệnh "chọn" sẽ mở ngăn kết quả mới. Tôi nghĩ tốt hơn là nên tạo một bảng nhật ký tạm thời để ghi lại các thông báo lỗi với dấu thời gian và tên thủ tục
mustafa kemal cá ngừ

28

Có, có một công cụ chuyên dụng cho loại việc này - MySQL Debugger .
nhập mô tả hình ảnh ở đây


5
tôi đã rất háo hức để thử nó. Thật không may nó là một đống đổ nát toàn bộ. Tôi nhận được thông báo lỗi "chức năng kết hợp không tồn tại" được cho là từ mysql, do đó các nhánh GUI không chính xác thông qua mã SP (mặc dù MySQL chạy nó chính xác). Chưa kể đến các biến cục bộ "DECLARE var DEFAULT value". Chúng chỉ hiển thị là NULL khi rõ ràng là không. Ồ, và cả "Định danh chưa khai báo: 'FETCH_RADIUS_DISTSORT'" trong đó đó là một câu lệnh đã biên dịch. Không được khuyến khích.
kellogs

4
Nó không hoàn hảo nhưng thử nghiệm của tôi với điều này là một trải nghiệm rất khác với trải nghiệm được @kellogs báo cáo ở trên. Công cụ này đẹp và nhẹ và dường như chỉ thực hiện công việc cần thiết mà không có bất kỳ sự cồng kềnh nào. Đó là một trải nghiệm tốt hơn nhiều đối với tôi so với bất kỳ công cụ nào khác được thử nghiệm (ví dụ như Visual Studio, Toad và dbForge Studio, tất cả đều có sai sót lớn - sẽ mô tả tất cả những công cụ này như một "đống đổ nát toàn bộ" khi so sánh). Không chắc liệu điều này có phải là do hàm đang được gỡ lỗi không bao gồm bất kỳ cấu trúc bị lỗi nào hay sự cố đã được khắc phục hay chưa.
Steve Chambers

2
Tôi cũng thấy công cụ này khá hữu ích để gỡ lỗi các thủ tục đã lưu trữ của tôi.
ralfe

22

Cách gỡ lỗi một thủ tục được lưu trữ MySQL.

Trình gỡ lỗi người nghèo:

  1. Tạo một bảng có tên là logtable với hai cột id INTlog VARCHAR(255).

  2. Làm cho cột id tự động tăng.

  3. Sử dụng quy trình này:

    delimiter //
    DROP PROCEDURE `log_msg`//
    CREATE PROCEDURE `log_msg`(msg VARCHAR(255))
    BEGIN
        insert into logtable select 0, msg;
    END
  4. Đặt mã này ở bất cứ đâu bạn muốn ghi tin nhắn vào bảng.

    call log_msg(concat('myvar is: ', myvar, ' and myvar2 is: ', myvar2));

Đó là một trình ghi nhật ký nhỏ nhanh chóng và tốt đẹp để tìm ra những gì đang xảy ra.



10

Trình gỡ lỗi cho mysql là tốt nhưng nó không miễn phí. Đây là những gì tôi sử dụng bây giờ:

DELIMITER GO$

DROP PROCEDURE IF EXISTS resetLog

GO$

Create Procedure resetLog() 
BEGIN   
    create table if not exists log (ts timestamp default current_timestamp, msg varchar(2048)) engine = myisam; 
    truncate table log;
END; 

GO$

DROP PROCEDURE IF EXISTS doLog 

GO$

Create Procedure doLog(in logMsg nvarchar(2048))
BEGIN  
  insert into log (msg) values(logMsg);
END;

GO$

Cách sử dụng trong thủ tục được lưu trữ:

call dolog(concat_ws(': ','@simple_term_taxonomy_id',  @simple_term_taxonomy_id));

sử dụng thủ tục được lưu trữ:

call resetLog ();
call stored_proc();
select * from log;

8

Một cách khác được trình bày ở đây

http://gilfster.blogspot.co.at/2006/03/debugging-stored-procedures-in-mysql.html

với thủ tục gỡ lỗi mySql tùy chỉnh và bảng ghi nhật ký.

Bạn cũng có thể chỉ cần đặt một lựa chọn đơn giản trong mã của mình và xem liệu nó có được thực thi hay không.

SELECT 'Message Text' AS `Title`; 

Tôi lấy ý tưởng này từ

http://forums.mysql.com/read.php?99,78155,78225#msg-78225

Ngoài ra, ai đó đã tạo một mẫu cho các thủ tục gỡ lỗi tùy chỉnh trên GitHub.

Xem tại đây

http://www.bluegecko.net/mysql/debugging-stored-procedures/ https://github.com/CaptTofu/Stored-procedure-debugging-routines

Đã được đề cập ở đây

Làm thế nào để bắt bất kỳ ngoại lệ nào trong trình kích hoạt và lưu trữ các thủ tục cho mysql?


7

Tôi chỉ cần đặt các câu lệnh được chọn vào các khu vực chính của quy trình được lưu trữ để kiểm tra trạng thái hiện tại của tập dữ liệu và sau đó nhận xét chúng (--select ...) hoặc loại bỏ chúng trước khi sản xuất.


7

Tôi đến bữa tiệc muộn, nhưng mang thêm bia:

http://ocelot.ca/blog/blog/2015/03/02/the-ocelotgui-debugger/https://github.com/ocelot-inc/ocelotgui

Tôi đã thử và nó có vẻ khá ổn định, hỗ trợ Kiểm tra điểm ngắt và biến.

Nó không phải là một bộ hoàn chỉnh (chỉ 4,1 Mb) nhưng đã giúp tôi rất nhiều!

Cách hoạt động: Nó tích hợp với máy khách mysql của bạn (tôi đang sử dụng Ubuntu 14.04) và sau khi bạn thực thi:

$install
$setup yourFunctionName

Nó cài đặt một cơ sở dữ liệu mới tại máy chủ của bạn, điều khiển quá trình gỡ lỗi. Vì thế:

$debug yourFunctionName('yourParameter')

sẽ cung cấp cho bạn cơ hội để xem từng bước mã của bạn và "làm mới" các biến của bạn, bạn có thể xem rõ hơn những gì đang diễn ra bên trong mã của mình.

Mẹo quan trọng: trong khi gỡ lỗi, có thể bạn sẽ thay đổi (tạo lại quy trình). Sau khi tạo lại, hãy thực thi: $ exit và $ setup trước khi gỡ lỗi $ mới

Đây là một giải pháp thay thế cho các phương pháp "chèn" và "nhật ký". Mã của bạn vẫn không có hướng dẫn "gỡ lỗi" bổ sung.

Ảnh chụp màn hình:

bước ngắt điểm ocelot


6

MySQL Connector / Net 6.6 có một tính năng để gỡ lỗi các thủ tục và chức năng đã lưu trữ

Cài đặt Trình gỡ lỗi

Để bật trình gỡ lỗi thủ tục được lưu trữ:

  • Đối với Connector / Net 6.6: Cài đặt Connector / Net 6.6 và chọn tùy chọn Complete.
  • Đối với Connector / Net 6.7 trở lên: Cài đặt sản phẩm MySQL cho Visual Studio, chứa trình gỡ lỗi thủ tục được lưu trữ.

Khởi động trình gỡ lỗi

Để khởi động trình gỡ lỗi, hãy làm theo các bước sau:

  • Chọn một kết nối trong Visual Studio Server Explorer.
  • Mở rộng thư mục Thủ tục đã Lưu trữ. Chỉ các thủ tục được lưu trữ mới có thể được gỡ lỗi trực tiếp. Để gỡ lỗi một hàm do người dùng xác định, hãy tạo một
    thủ tục được lưu trữ gọi hàm.
  • Bấm vào nút thủ tục được lưu trữ, sau đó bấm chuột phải và từ menu ngữ cảnh chọn Quy trình gỡ lỗi.

5

MySql Connector / NET cũng bao gồm một trình gỡ lỗi thủ tục được lưu trữ tích hợp trong visual studio kể từ phiên bản 6.6, Bạn có thể tải xuống trình cài đặt và nguồn tại đây: http://dev.mysql.com/downloads/connector/net/

Một số tài liệu / ảnh chụp màn hình: https://dev.mysql.com/doc/visual-studio/en/visual-studio-debugger.html

Bạn có thể theo dõi thông báo tại đây: http://forums.mysql.com/read.php?38,561817,561817#msg-561817

CẬP NHẬT: MySql cho Visual Studio đã được tách từ Connector / NET thành một sản phẩm riêng biệt, bạn có thể chọn nó (bao gồm cả trình gỡ lỗi) từ đây https://dev.mysql.com/downloads/windows/visualstudio/1.2.html (vẫn miễn phí và mã nguồn mở).

KHUYẾN CÁO: Tôi là nhà phát triển đã tạo ra công cụ gỡ lỗi các thủ tục đã lưu trữ cho sản phẩm MySQL cho Visual Studio.


Đã xảy ra sự cố với chuỗi kết nối đa máy chủ khi sử dụng MySQL và Connector .NET. Tôi đã giải thích vấn đề ở đây .. Tôi đã tự hỏi liệu có ai sẽ xem xét vấn đề này không? Điều này đã gây ra khá nhiều vấn đề đối với nhiều nhà phát triển chúng tôi Net người sử dụng MySQL ...
Hooman Bahreini

1
Rất tiếc khi biết điều đó, tôi không còn làm việc tại Oracle và không có nhiều thời gian rảnh, tôi khuyên bạn nên liên hệ với bộ phận hỗ trợ của MySQL.
Fernando Gonzalez Sanchez

4

Trình gỡ lỗi đầu tiên và ổn định cho MySQL nằm trong dbForge Studio cho MySQL


3

Tôi đã sử dụng hai công cụ khác nhau để gỡ lỗi các thủ tục và hàm:

  1. dbForge - GUI mysql nhiều chức năng.
  2. MyDebugger - công cụ chuyên dùng để gỡ lỗi ... công cụ tiện dụng để gỡ lỗi. bình chọn http://tinyurl.com/voteimg

3

Biến do người dùng MySQL xác định (được chia sẻ trong phiên) có thể được sử dụng làm đầu ra ghi nhật ký:

DELIMITER ;;
CREATE PROCEDURE Foo(tableName VARCHAR(128))
BEGIN
  SET @stmt = CONCAT('SELECT * FROM ', tableName);
  PREPARE pStmt FROM @stmt;
  EXECUTE pStmt;
  DEALLOCATE PREPARE pStmt;
  -- uncomment after debugging to cleanup
  -- SET @stmt = null;
END;;
DELIMITER ;
call Foo('foo');
select @stmt;

sẽ xuất:

SELECT * FROM foo

1

Cóc mysql. Có một phiên bản phần mềm miễn phí http://www.quest.com/toad-for-mysql/


1
Tôi đã sử dụng Toad trong nhiều năm nhưng không biết nó có bất kỳ tính năng đặc biệt nào để gỡ lỗi rau mầm. Bạn có thể nói rõ cách bạn sử dụng Toad để làm như vậy không?
Cory House

Nhìn vào Toad 6.3 cho mysql ngay bây giờ, có vẻ như có tính năng gỡ lỗi với các điểm ngắt và mọi thứ. Bạn có nghĩa là tính năng gỡ lỗi không hoạt động? Hoặc có thể phiên bản của bạn cũ hơn và không bao gồm tính năng gỡ lỗi?
Joyce

1

Câu trả lời tương ứng với điều này bởi @Brad Parks Không chắc chắn về phiên bản MySQL, nhưng của tôi là 5.6, do đó, một chút tinh chỉnh hoạt động:

Tôi đã tạo một hàm debug_msglà hàm (không phải thủ tục) và trả về văn bản (không giới hạn ký tự) và sau đó gọi hàm là SELECT debug_msg(params) AS my_res_set, mã như dưới đây:

CREATE DEFINER=`root`@`localhost` FUNCTION `debug_msg`(`enabled` INT(11), `msg` TEXT) RETURNS text CHARSET latin1
    READS SQL DATA
BEGIN
    IF enabled=1 THEN
    return concat('** DEBUG:', "** ", msg);
    END IF;
END

DELIMITER $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `proc_func_call`(
 IN RegionID VARCHAR(20),
 IN RepCurrency INT(11),
 IN MGID INT(11),
 IN VNC VARCHAR(255)
)
BEGIN
    SET @enabled = TRUE;
    SET @mainQuery = "SELECT * FROM Users u";
    SELECT `debug_msg`(@enabled, @mainQuery) AS `debug_msg1`;
    SET @lastQuery = CONCAT(@mainQuery, " WHERE u.age>30);
    SELECT `debug_msg`(@enabled, @lastQuery) AS `debug_msg2`;
END $$
DELIMITER
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.