PHP Script to fix MySQL columns to work with strict-mode

こ雲淡風輕ζ 提交于 2019-12-11 16:04:34

问题


I'm trying to build a script to generate ALTER TABLE queries so that across whole schemas, columns are adjusted to be compatible with MySQL strict-mode..

I want it to be a simple as possible, making the most basic changes possible for NOT/NOT NULL and Default values to ensure strict-mode compatibility, but at the same time minimising the chances of breaking any existing queries, or associated PHP code that depends on the schema definition's workings.

Any tips / things I've missed out / things I maybe doing wrong..? BTW, I don't think I need to cover absolutely every column type available in MySQL, as I simply don't use some of them. But a few extra 'case:' statements wouldn't go amiss .. ;)

<?
include "common.inc.php";
include "header.inc.php";

$r_resultTables = dbQuery("SHOW TABLES");

echo '<textarea style="width: 95%; height: 80vh;">';
while ($a_rowTable = dbFetchRow($r_resultTables)) {
    $table = dbEscape($a_rowTable[0]);

    $tableNameAdded = false;

    $r_result = dbQuery("SHOW FULL FIELDS FROM `$table`");
    while ($a_row = dbFetchAssoc($r_result)) {

        $comment = null;
        $default = (($a_row['Default'] != NULL) ? "DEFAULT '" . $a_row['Default'] . "'" : '');
        $extra = null;

        $type = strtok($a_row['Type'],'(');

        $field = dbEscape($a_row['Field']);

        // Is the field allowed to be null?
        if ($a_row['Null'] == 'YES') {
            $nullable = 'NULL';
        } else {
            $nullable = 'NOT NULL';
        }

        // skip nullable fields with no set default (they will default to NULL)
        if (($a_row['Default'] === NULL) AND ($a_row['Null'] == 'YES')) {
            continue;
        }

        // skip PK fields
        if ($a_row['Key'] == 'PRI') { continue; }

        // fields that need a set default if they don't have one
        if ($a_row['Default'] === NULL) {
            switch ($type) {
                case 'int':
                case 'smallint':
                case 'tinyint':
                case 'mediumint':
                case 'bigint':
                case 'decimal':
                case 'numeric':
                case 'float':
                case 'double':
                    $comment = "Numeric field should have '0' as default (if missing)";
                    $default = "DEFAULT '0'";
                    break;
                case 'char':
                case 'varchar':
                    $comment = "(VAR)CHAR fields should have empty string as default (if missing)";
                    $default = "DEFAULT ''";
                    break;
            }
        }

        // fields that need changing anyway if they're not already nullable, or can be skipped
        switch ($type) {
            case 'datetime':
            case 'date':
            case 'timestamp':
            case 'year':
            case 'time':
                if (substr($a_row['Default'],0,2) == '00') {
                    $comment = "Date/Time types cannot default to zeroes, should be NULLable (if missing)";
                    $extra = "UPDATE `$table` SET `$field` = NULL WHERE `$field` = '" . $a_row['Default'] . "';";
                    $default = "DEFAULT NULL";
                } elseif ($a_row['Default'] == 'CURRENT_TIMESTAMP') {
                    continue 2;
                } else {
                    $comment = "Date/Time types should be NULLable if missing";
                }
                $nullable = 'NULL';
                break;
            case 'enum':
            case 'set':
                continue 2; // ENUM and SET types don't need any change
                break;
            case 'tinytext':
            case 'text':
            case 'mediumtext':
            case 'longtext':
                continue 2; // TEXT types cannot have a default value
                break;
            default:
                if ($a_row['Default'] !== NULL) { continue 2; } // skip any other types that already have defaults
                break;
        }

        if (!$tableNameAdded) {
            echo "\r\n# `$table`\r\n\r\n";
            $tableNameAdded = true;
        }

        // Alter table query
        if ($comment) { echo '# `' . $field . '` - ' . $comment . "\r\n"; } else { echo "# UNKNOWN\r\n" .  '# '; }
        echo  "ALTER TABLE `$table` CHANGE `$field` `$field` $a_row[Type] $nullable $default;\r\n";
        if ($extra) { echo $extra . "\r\n"; }
        echo "\r\n";
    }
}
echo '</textarea>';

include "footer.inc.php";

Using the default values info from here: https://dev.mysql.com/doc/refman/5.7/en/data-type-defaults.html

And strict mode info from here: https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html

来源:https://stackoverflow.com/questions/55673938/php-script-to-fix-mysql-columns-to-work-with-strict-mode

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!