Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Có thể xem dữ liệu nào đã được thay đổi bởi một truy vấn không?

ĐƯỢC RỒI. Giải pháp của tôi là sự kết hợp giữa PHP và MySQL để làm cho điều này hoạt động "minh bạch" nhất có thể.

Các phương pháp này tồn tại trong một Data lớp wrapper sử dụng PDO và các câu lệnh đã chuẩn bị.

Một số giải thích về các phương pháp khác được sử dụng:

  • Data::prepareAndExecute ($query, $tokens); là một phương thức phím tắt chuẩn bị một truy vấn, thực thi nó và nếu có kết quả, trả về một mảng kết hợp của những kết quả đó.
  • Data::isSafeDatabaseEntity ($table) chỉ cần kiểm tra xem tên bảng có phù hợp với preg_match ("/^([a-zA-Z0-9_]+)$/", $check); lệnh để ngăn chặn việc đưa vào SQL. Điều này là do tôi không thể sử dụng các câu lệnh đã chuẩn bị sẵn cho tên trường và bảng.
  • Data::tableInfo ($table); trả về một mảng kết hợp của các cột trong bảng dựa trên thông tin nhận được từ PDOStatement::getColumnMeta (); .
  • Data::getTablePrimaryKey ($table); sử dụng kết quả của SHOW INDEX FROM... truy vấn. Cần phải nói rằng điều này được thiết kế để chỉ hoạt động với PK trường đơn.

Trích xuất từ ​​Data của tôi lớp:

public static function addTableLogging ($table, $ignorecolumns = array ())
{
    if (Data::isSafeDatabaseEntity ($table))
    {
        $update_trigger = "CREATE TRIGGER `{$table}_after_update` AFTER UPDATE ON `{$table}` FOR EACH ROW BEGIN\n";
        $insert_trigger = "CREATE TRIGGER `{$table}_after_insert` AFTER INSERT ON `{$table}` FOR EACH ROW BEGIN\n";
        $columns = Data::tableInfo ($table);
        $pk = Data::getTablePrimaryKey ($table);
        foreach ($columns as $column)
        {
            if (!in_array ($column ['name'], $ignorecolumns))
            {
                $update_trigger .= "   IF (NEW.{$column ['name']} != OLD.{$column ['name']}) THEN
     CALL changelog_store ('{$table}', OLD.{$pk}, '{$column ['name']}', OLD.{$column ['name']}, NEW.{$column ['name']});
  END IF;\n";
                $insert_trigger .= "   CALL changelog_store ('{$table}', NEW.{$pk}, '{$column ['name']}', '', NEW.{$column ['name']});\n";
            }
        }
        $update_trigger .= "END";
        $insert_trigger .= "END";

        self::removeTableLogging ($table);
        self::prepareAndExecute ($update_trigger);
        self::prepareAndExecute ($insert_trigger);
    }
}

public static function removeTableLogging ($table)
{
    if (self::isSafeDatabaseEntity ($table))
    {
        Data::prepareAndExecute ("DROP TRIGGER IF EXISTS `{$table}_after_update`;");
        Data::prepareAndExecute ("DROP TRIGGER IF EXISTS `{$table}_after_insert`;");
    }
}

public static function refreshLoggingProcedure ()
{
    /* -- for logging into MySQL Table:
      CREATE TABLE `changelog` (
        `change_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
        `change_table` VARCHAR(50) NULL DEFAULT NULL,
        `change_table_id` VARCHAR(25) NULL DEFAULT NULL,
        `change_field` VARCHAR(50) NULL DEFAULT NULL,
        `change_old` VARCHAR(255) NULL DEFAULT NULL,
        `change_new` VARCHAR(255) NULL DEFAULT NULL,
        `change_user` INT(10) UNSIGNED NOT NULL DEFAULT '0',
        `change_date` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
        PRIMARY KEY (`change_id`),
        INDEX `change_table_id` (`change_table_id`),
        INDEX `change_table` (`change_table`, `change_field`)
      );
    */
    $logquery = "CREATE PROCEDURE `changelog_store`(IN `tab` VARCHAR(50), IN `pkval` INT, IN `fieldn` VARCHAR(50), IN `oldv` TEXT, IN `newv` TEXT)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
    IF ISNULL(@STAFFID) THEN
        SET @STAFFID = 0;
    END IF;
    INSERT INTO `changelog` (change_table, change_table_id, change_field, change_old, change_new, change_date, change_user)
        VALUES (tab, pkval, fieldn, oldv, newv, NOW(), @STAFFID);
END";
    Data::prepareAndExecute ("DROP PROCEDURE IF EXISTS `changelog_store`;");
    Data::prepareAndExecute ($logquery);
}



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. khóa chính tổng hợp và cột tự động gia tăng nhưng KHÔNG phải khóa chính

  2. Đồng bộ hóa cơ sở dữ liệu máy khách SQLite với cơ sở dữ liệu máy chủ MySQL

  3. ln:/usr/lib/libmysqlclient.18.dylib:Tệp tồn tại

  4. cố gắng lấy số tháng

  5. Cách lọc kết quả SQL trong một quan hệ có-nhiều-qua