sql >> データベース >  >> RDS >> Mysql

クエリによって変更されたデータを確認することはできますか?

    わかった。私の解決策は、PHPとMySQLを組み合わせて、これを可能な限り「透過的に」機能させることです。

    これらのメソッドはDataに存在します PDOとプリペアドステートメントを使用するラッパークラス。

    使用された他の方法の説明:

    • Data::prepareAndExecute ($query, $tokens); は、クエリを準備して実行し、結果がある場合はそれらの結果の連想配列を返すショートカットメソッドです。
    • Data::isSafeDatabaseEntity ($table) テーブル名がpreg_match ("/^([a-zA-Z0-9_]+)$/", $check);に適合することを確認するだけです。 SQLインジェクションを防ぐコマンド。これは、フィールド名とテーブル名にプリペアドステートメントを使用できないためです。
    • Data::tableInfo ($table); PDOStatement::getColumnMeta ();から受け取った情報に基づいて、テーブル内の列の連想配列を返します。 。
    • Data::getTablePrimaryKey ($table); SHOW INDEX FROM...の結果を使用します クエリ。これは、単一フィールドPKでのみ機能するように設計されていると言えます。

    Dataからの抜粋 クラス:

    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. 関数名をデータベースに保存して実行します

    2. PostgreSQL監査ログのベストプラクティス

    3. MySQL-正確な関連性のある検索結果を取得する方法

    4. JavaJDBCを介したiBATISを使用したOracleSQLDATE変換の問題