Bagaimana Anda men-debug prosedur tersimpan MySQL?

125

Proses saya saat ini untuk men-debug prosedur tersimpan sangat sederhana. Saya membuat tabel yang disebut "debug" di mana saya memasukkan nilai variabel dari prosedur tersimpan saat dijalankan. Ini memungkinkan saya untuk melihat nilai variabel apa pun pada titik tertentu dalam skrip, tetapi adakah cara yang lebih baik untuk men-debug prosedur tersimpan MySQL?

Cory House
sumber
2
Apakah ada opsi GUI untuk pengguna non-Windows? Harus menjalankan salinan Windows hanya untuk men-debug prosedur yang tersimpan adalah sedikit lompatan. Dan sebagian besar opsi penyisipan tabel gagal jika Anda berada dalam transaksi yang akan Anda rollback.
Kode Abominator

Jawaban:

44

Saya melakukan sesuatu yang sangat mirip dengan Anda.

Saya biasanya akan menyertakan parameter DEBUG yang secara default disetel ke false dan dapat disetel ke true pada waktu proses. Kemudian bungkus pernyataan debug ke dalam blok "If DEBUG".

Saya juga menggunakan tabel pencatatan dengan banyak pekerjaan saya sehingga saya dapat meninjau proses dan waktu. Kode Debug saya mendapatkan output di sana juga. Saya menyertakan nama param panggilan, deskripsi singkat, jumlah baris yang terpengaruh (jika sesuai), bidang komentar dan cap waktu.

Alat debugging yang baik adalah salah satu kegagalan menyedihkan dari semua platform SQL.

Bob Probst
sumber
3
Tidak semua platform @Bob Probst, alat debugging sybase cukup baik dengan debug breakpoint untuk pemicu dan prosedur tersimpan
Anup
69

debug_msgProsedur berikut dapat dipanggil untuk hanya mengeluarkan pesan debug ke konsol:

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 ;

Kemudian jalankan tes seperti ini:

CALL test_procedure(1,2)

Ini akan menghasilkan output berikut:

** DEBUG:
** my first debug message
** DEBUG:
** arg1:1
** DEBUG:
** This message always shows up
Brad Parks
sumber
8
Ini sepertinya tidak berhasil untuk FUNCTIONS dan saya tidak tahu mengapa. Itu selalu memberikan "Kode Kesalahan: 1415. Tidak diizinkan untuk mengembalikan hasil yang ditetapkan dari suatu fungsi". Apakah ada jalan lain?
Patrick M
1
Fungsi @PatrickM tidak dapat mengembalikan baris ("hasil") sementara prosedur debug ini bergantung padanya (pesan debug adalah kumpulan hasil yang dikembalikan dalam panggilan prosedur). Dalam fungsi, Anda hanya dapat INSERT INTO my_log_table (message) VALUES (msg)dan mungkin mengambil semua pesan debug setelah panggilan fungsi selesai (yaitu: Anda kembali ke prosedur)
Xenos
Pendekatan ini bagus tetapi menulis ke konsol tidak efektif di MySQL Workbench seperti IDE. karena setiap pernyataan "pilih" membuka panel hasil baru. Saya pikir lebih baik membuat tabel log sementara untuk mencatat pesan kesalahan dengan cap waktu dan nama prosedur
mustafa kemal tuna
28

Ya, ada alat khusus untuk hal semacam ini - MySQL Debugger .
masukkan deskripsi gambar di sini

George
sumber
5
saya sangat ingin mencobanya. Sayangnya itu adalah reruntuhan total. Saya mendapatkan pesan kesalahan "fungsi menyatu tidak ada" suppsedly dari mysql, akibatnya cabang GUI salah melalui kode SP (meskipun MySQL menjalankannya dengan benar). Belum lagi variabel lokal "DECLARE var DEFAULT value". Mereka hanya muncul sebagai NULL padahal sebenarnya tidak. Oh, dan juga "Pengenal yang tidak dideklarasikan: 'FETCH_RADIUS_DISTSORT'" yang merupakan pernyataan yang dikompilasi. Tidak direkomendasikan.
kellogs
4
Ini tidak sempurna tetapi percobaan saya dengan ini merupakan pengalaman yang sangat berbeda dengan yang dilaporkan oleh @kellogs di atas. Alat ini bagus dan ringan dan tampaknya melakukan pekerjaan yang diperlukan tanpa membengkak. Itu adalah pengalaman yang jauh lebih baik bagi saya daripada alat lain yang diujicobakan (yaitu Visual Studio, Toad dan dbForge Studio, yang semuanya memiliki kekurangan utama - akan menggambarkan semua ini sebagai "total reruntuhan" dalam perbandingan). Tidak yakin apakah ini karena fungsi yang sedang di-debug tidak menyertakan salah satu konstruksi yang salah atau apakah masalah telah diperbaiki.
Steve Chambers
2
Saya juga menemukan alat ini cukup berguna untuk men-debug prosedur tersimpan saya.
ralfe
22

Cara men-debug prosedur tersimpan MySQL.

Debugger orang miskin:

  1. Buat tabel bernama logtable dengan dua kolom, id INTdan log VARCHAR(255).

  2. Buat autoincrement kolom id.

  3. Gunakan prosedur ini:

    delimiter //
    DROP PROCEDURE `log_msg`//
    CREATE PROCEDURE `log_msg`(msg VARCHAR(255))
    BEGIN
        insert into logtable select 0, msg;
    END
  4. Letakkan kode ini di mana pun Anda ingin memasukkan pesan ke tabel.

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

Ini adalah logger kecil yang cepat dan kotor untuk mencari tahu apa yang sedang terjadi.

Eric Leschinski
sumber
21

Ada alat GUI untuk men-debug prosedur / fungsi yang tersimpan dan skrip di MySQL. Alat yang layak dbForge Studio for MySQL, memiliki fungsionalitas dan stabilitas yang kaya.

Josef Miran
sumber
Sulit menemukan platform tempat alat debug dijalankan. Sepertinya berjalan di Windows. Ada yang lain?
Guy
10

Debugger untuk mysql bagus tapi tidak gratis. Inilah yang saya gunakan sekarang:

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$

Penggunaan dalam prosedur tersimpan:

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

penggunaan prosedur tersimpan:

call resetLog ();
call stored_proc();
select * from log;
Nada Škoda
sumber
8

Cara lain disajikan di sini

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

dengan prosedur custom debug mySql dan tabel logging.

Anda juga dapat menempatkan pemilihan sederhana dalam kode Anda dan melihat apakah itu dijalankan.

SELECT 'Message Text' AS `Title`; 

Saya mendapat ide ini dari

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

Juga seseorang membuat template untuk prosedur debug kustom di GitHub.

Lihat disini

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

Disebutkan di sini

Bagaimana cara menangkap pengecualian dalam pemicu dan prosedur penyimpanan untuk mysql?

Jeremy S.
sumber
7

Saya hanya menempatkan pernyataan pilih di area utama dari prosedur tersimpan untuk memeriksa status kumpulan data saat ini, dan kemudian mengomentarinya (--select ...) atau menghapusnya sebelum produksi.

Mesin Abu
sumber
7

Saya terlambat ke pesta, tetapi membawa lebih banyak bir:

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

Saya mencoba, dan tampaknya cukup stabil, mendukung Breakpoints dan inspeksi Variabel.

Ini bukan suite yang lengkap (hanya 4,1 Mb) tetapi sangat membantu saya!

Cara kerjanya: Terintegrasi dengan klien mysql Anda (saya menggunakan Ubuntu 14.04), dan setelah Anda mengeksekusi:

$install
$setup yourFunctionName

Ini menginstal database baru di server Anda, yang mengontrol proses debugging. Begitu:

$debug yourFunctionName('yourParameter')

akan memberi Anda kesempatan untuk menjalankan kode Anda langkah demi langkah, dan "menyegarkan" variabel Anda, Anda dapat melihat dengan lebih baik apa yang terjadi di dalam kode Anda.

Tip Penting: saat debugging, mungkin Anda akan berubah (membuat ulang prosedur). Setelah membuat ulang, jalankan: $ exit dan $ setup sebelum $ debug baru

Ini adalah alternatif untuk metode "menyisipkan" dan "log". Kode Anda tetap bebas dari instruksi "debug" tambahan.

Tangkapan layar:

ocelot breakpoint melangkah

Marcelo Amorim
sumber
6

Konektor MySQL / Net 6.6 memiliki fitur untuk Debug Stored Procedures and Functions

Menginstal Debugger

Untuk mengaktifkan debugger prosedur tersimpan:

  • Untuk Connector / Net 6.6: Instal Connector / Net 6.6 dan pilih opsi Complete.
  • Untuk Connector / Net 6.7 dan yang lebih baru: Instal produk MySQL untuk Visual Studio, yang merupakan tempat penyimpanan prosedur tersimpan.

Memulai Debugger

Untuk memulai debugger, ikuti langkah-langkah berikut:

  • Pilih koneksi di Visual Studio Server Explorer.
  • Perluas folder Stored Procedures. Hanya prosedur tersimpan yang dapat di-debug secara langsung. Untuk men-debug fungsi yang ditentukan pengguna, buat
    prosedur tersimpan yang memanggil fungsi tersebut.
  • Klik pada node prosedur tersimpan, lalu klik kanan dan dari menu konteks pilih Rutinitas Debug.
Rahul Tripathi
sumber
5

MySql Connector / NET juga menyertakan prosedur debugger tersimpan yang terintegrasi dalam studio visual mulai versi 6.6, Anda bisa mendapatkan penginstal dan sumbernya di sini: http://dev.mysql.com/downloads/connector/net/

Beberapa dokumentasi / tangkapan layar: https://dev.mysql.com/doc/visual-studio/en/visual-studio-debugger.html

Anda dapat mengikuti pengumuman di sini: http://forums.mysql.com/read.php?38,561817,561817#msg-561817

UPDATE: MySql untuk Visual Studio dipisahkan dari Connector / NET menjadi produk terpisah, Anda dapat memilihnya (termasuk debugger) dari sini https://dev.mysql.com/downloads/windows/visualstudio/1.2.html (masih gratis & open source).

PENAFIAN: Saya adalah pengembang yang menulis mesin debugger prosedur tersimpan untuk produk MySQL untuk Visual Studio.

Fernando Gonzalez Sanchez
sumber
Ada masalah dengan string koneksi multi-host saat menggunakan MySQL dan Connector .NET. Saya telah menjelaskan masalahnya di sini ... Saya ingin tahu apakah ada yang akan menyelidiki masalah ini? Ini telah menyebabkan sedikit masalah bagi banyak dari kita. Pengembang bersih yang menggunakan MySQL ...
Hooman Bahreini
1
Mohon maaf karena saya tidak lagi bekerja di Oracle, dan tidak memiliki banyak waktu luang, saya sarankan untuk menghubungi dukungan MySQL.
Fernando Gonzalez Sanchez
4

Debugger pertama dan stabil untuk MySQL ada di dbForge Studio untuk MySQL

Zoitc2014
sumber
3

Saya telah menggunakan dua alat berbeda untuk men-debug prosedur dan fungsi:

  1. dbForge - banyak GUI mysql fungsional.
  2. MyDebugger - alat khusus untuk debugging ... alat praktis untuk debugging. pilih http://tinyurl.com/voteimg
GeoGo
sumber
3

Variabel yang ditentukan pengguna MySQL (dibagi dalam sesi) dapat digunakan sebagai keluaran logging:

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;

akan mengeluarkan:

SELECT * FROM foo
clarkttfu
sumber
1

Toad mysql. Ada versi freeware http://www.quest.com/toad-for-mysql/

Joyce
sumber
1
Saya telah menggunakan Toad selama bertahun-tahun tetapi tidak menyadarinya memiliki fitur khusus untuk men-debug sprocs. Bisakah Anda menjelaskan bagaimana Anda menggunakan Toad untuk melakukannya?
Cory House
Melihat Toad 6.3 untuk mysql barusan, sepertinya ada fitur debug dengan breakpoints dan semuanya. Apakah maksud Anda fitur debug tidak berfungsi? Atau mungkin versi Anda lebih lama & tidak menyertakan fitur debug?
Joyce
1

Jawaban yang sesuai dengan ini oleh @Brad Parks Tidak yakin tentang versi MySQL, tetapi milik saya adalah 5.6, maka sedikit pekerjaan tweaker:

Saya membuat fungsi debug_msgyang berfungsi (bukan prosedur) dan mengembalikan teks (tanpa batas karakter) dan kemudian memanggil fungsi tersebut sebagai SELECT debug_msg(params) AS my_res_set, kode seperti di bawah ini:

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
aniruddha
sumber