Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Membangun Kode MySQL secara dinamis untuk membuat pemicu

Karena tidak menerima solusi pasti untuk pertanyaan ini, saya telah melanjutkan untuk membuat opsi bukti konsep (karena MySQL secara asli tidak akan membiarkan Anda menjalankan kode SQL yang membuat pemicu, menggunakan Pernyataan yang Disiapkan). Jangan ragu untuk memberikan masukan positif.

DELIMITER //
DROP PROCEDURE IF EXISTS createAuditTable//
CREATE PROCEDURE createAuditTable(tblname CHAR(30), sufftxt CHAR(10), pri CHAR(20), filename CHAR(255) )
BEGIN
    SELECT DATABASE() INTO @dbname;
    SET @srctbl = CONCAT(@dbname, ".", tblname);
    SET @destdb = CONCAT(@dbname, "_", sufftxt);
    SET @desttbl = CONCAT(@destdb, ".", tblname);

    SET @str1 = CONCAT( "CREATE DATABASE IF NOT EXISTS ", @destdb);
    PREPARE stmt1 FROM @str1;
    EXECUTE stmt1;
    DEALLOCATE PREPARE stmt1;

    SET @str2 = "SET FOREIGN_KEY_CHECKS=0";
    PREPARE stmt2 FROM @str2;
    EXECUTE stmt2;
    DEALLOCATE PREPARE stmt2;

    SELECT COUNT(*) FROM information_schema.tables WHERE table_name = tblname AND table_schema = @destdb INTO @tblcount;
    IF (@tblcount = 0) THEN 
        SET @str3 = CONCAT("CREATE TABLE ", @desttbl, " LIKE ", @srctbl);
        PREPARE stmt3 FROM @str3;
        EXECUTE stmt3;
        DEALLOCATE PREPARE stmt3;
    END IF;

    SELECT COUNT(*) FROM information_schema.columns WHERE table_name = tblname AND table_schema = @destdb AND column_key = 'PRI' INTO @keycount;

    IF (@keycount <> 0) THEN 
        SET @str4 = CONCAT("ALTER TABLE ", @desttbl, " DROP PRIMARY KEY, ADD INDEX ", pri, " (", pri, ")" );
        PREPARE stmt4 FROM @str4;
        EXECUTE stmt4;
        DEALLOCATE PREPARE stmt4;
    END IF;

SELECT CONCAT( "DELIMITER $$
DROP TRIGGER IF EXISTS ", tblname, "_history_BU$$
CREATE TRIGGER ", tblname, "_history_BU
BEFORE UPDATE ON ", tblname, "
FOR EACH ROW
BEGIN
    INSERT INTO ", @desttbl, " (",
(SELECT GROUP_CONCAT(column_name) FROM information_schema.columns WHERE table_schema = @dbname AND table_name = tblname), ") ",
    "
    VALUES(", 
(SELECT GROUP_CONCAT('OLD.', column_name) FROM information_schema.columns WHERE table_schema = @dbname AND table_name = tblname),
 ");
END$$
DELIMITER ;"
 ) AS qstr FROM DUAL INTO @triggertxt;

SET @savestr = CONCAT('SELECT ', '"', @triggertxt, '"', " INTO DUMPFILE ", '"', filename, '"');
PREPARE stmt5 FROM @savestr;
EXECUTE stmt5;
DEALLOCATE PREPARE stmt5;


END//
DELIMITER ;  

UNTUK MENGGUNAKAN, panggil Prosedur:

CALL createAuditTable('name_of_table', 'history', 'pri_key_fld', 'path/to/file.sql');

Database baru dibuat menggunakan nama DB kerja Anda saat ini, dengan akhiran "_history" ditambahkan padanya. Tabel "name_of_table" dibuat di DB baru ini, identik dengan tabel asliBidang "pri_key_fld" (yang seharusnya menjadi kunci utama/unik tabel "name_of_table") diubah menjadi kunci "INDEX" biasa. Tujuannya adalah untuk mencegah pelanggaran unik selama pencatatan audit beberapa baris di masa mendatang.

KEMUDIAN Jalankan file yang dibuat dengan prosedur:SOURCE 'path/to/file.sql'; (atau sintaks alternatif apa pun untuk menjalankan SQL dari file itu)

Beberapa Peringatan:Saat ini, Anda hanya dapat menyediakan satu bidang untuk "pri_key_fld". Idealnya, kami ingin menyediakan "array" yang berisi semua bidang unik di tabel itu. Saat ini, jika Anda memiliki lebih dari satu bidang unik, pelanggaran unik akan mencegah Anda mencatat lebih dari satu baris. Dan itu tidak baik!

Sekali lagi, jelas sangat kikuk dan tidak berkinerja baik melalui proses pembuatan file di disk, hanya untuk membaca SQL dari file yang sama di perintah berikutnya. Salah satu alternatif yang dapat dijelajahi untuk memperbaikinya adalah ini:Jalankan CALL createAuditTable bagian dari baris perintah, tangkap output sebagai teks, lalu Jalankan sama seperti SQL di sana di baris perintah. Saya memang mencobanya di Windows PowerShell; tetapi outputnya penuh dengan string "\r\n" literal (mewakili jeda baris). Saya tidak punya waktu untuk segera membersihkan tali ini, jadi sekarang ada di lemari es!

Akhirnya, hai para ninja MySQL, tolong bersikap baiklah. Aku tidak pro, sungguh. Ini hanyalah upaya menumbuhkan-sendiri-bahan makanan untuk memecahkan masalah praktis.

Terima kasih.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bagaimana saya bisa membuat penginstal untuk situs web. PHP mysql

  2. Nilai '0000-00-00' tidak dapat direpresentasikan sebagai java.sql.Date

  3. Bagaimana saya bisa mengubah ukuran kolom dalam tabel MySQL?

  4. Database kosong di MySQL dan PHP?

  5. MySQL memesan posting dengan komentar terbaru ATAU posting terakhir