Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Czy można zobaczyć, jakie dane zostały zmienione przez zapytanie?

OK. Moje rozwiązanie to połączenie PHP i MySQL, aby działało to tak „przezroczyście”, jak to tylko możliwe.

Te metody istnieją w Data klasa wrapper wykorzystująca PDO i przygotowane instrukcje.

Wyjaśnienie innych zastosowanych metod:

  • Data::prepareAndExecute ($query, $tokens); to metoda skrótu, która przygotowuje zapytanie, wykonuje je i, jeśli są wyniki, zwraca tablicę asocjacyjną tych wyników.
  • Data::isSafeDatabaseEntity ($table) po prostu sprawdza, czy nazwa tabeli pasuje do preg_match ("/^([a-zA-Z0-9_]+)$/", $check); polecenie, aby zapobiec wstrzyknięciu SQL. Dzieje się tak, ponieważ nie mogę używać przygotowanych instrukcji dla nazw pól i tabel.
  • Data::tableInfo ($table); zwraca tablicę asocjacyjną kolumn w tabeli na podstawie informacji otrzymanych z PDOStatement::getColumnMeta (); .
  • Data::getTablePrimaryKey ($table); używa wyników SHOW INDEX FROM... zapytanie. Należy powiedzieć, że jest to zaprojektowane do pracy tylko z jednopolowymi PK.

Wyciągi z moich Data klasa:

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. MySQL:Używanie DATETIME jako klucza podstawowego

  2. dwa słowa i spacje nie działają w zapytaniu MYSQL przy użyciu LIKE

  3. Spowodowane przez:java.time.DateTimeException:Znaleziono konflikt:Pole DayOfWeek 6 różni się od DayOfWeek 2 pochodzącego z 30.01.2016

  4. Jak korzystać z metody password_hash() w php..?

  5. MySQL – Naprawa – Błąd – Twoje hasło nie spełnia aktualnych wymagań politycznych