检查SQL模式中的保留字并找到合适的替换

时间:2017-09-05 11:42:59

标签: mysql sql mariadb reserved-words

我的数据库故障排除了几个小时,其中包含maxValue作为列名。我发现这是一个保留词。

我已经使用typetimestamp同时使用了MySQL和MariaDB,但是我已经吸取了教训,并且再也不会这样做了(MySQL表明两者都是保留,但MariaDB只显示timestamp,甚至说它仍然可以使用)。

  1. 是否有某种在线工具可以使用SQL转储检查架构或为保留字创建SQL?
  2. 是否有任何资源或策略显示典型的替换词。我想我可以让它们复数,但这样做违背了我的人事标准。

1 个答案:

答案 0 :(得分:0)

对于它的价值,这是一个工具......

请注意,MariaDB 10.2.7不支持mysql.help_keyword,我不得不对保留字进行硬编码。

<?php
error_reporting(E_ALL);
ini_set('display_startup_errors', 1);
ini_set('display_errors', 1);
openlog('API', LOG_NDELAY, LOG_LOCAL2);

if ($_SERVER['REQUEST_METHOD'] == 'POST' && !empty($_POST['database'])) {

    $db=parse_ini_file(__DIR__.'/../config.ini',true)['mysql'];
    $pdo=new PDO("mysql:host={$db['host']};dbname={$db['dbname']};charset={$db['charset']}",$db['username'],$db['password'],array(PDO::ATTR_EMULATE_PREPARES=>false,PDO::MYSQL_ATTR_USE_BUFFERED_QUERY=>true,PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION,PDO::ATTR_DEFAULT_FETCH_MODE=>PDO::FETCH_OBJ));

    $error=['tableHelper'=>[],'columnHelper'=>[],'tableMdbReserved'=>[],'columnMdbReserved'=>[],'tableMdbException'=>[],'columnMdbException'=>[]];
    $stmt=$pdo->query('SELECT name FROM mysql.help_keyword');
    $reserved=$stmt->fetchAll(PDO::FETCH_COLUMN);
    $mdbReserved=['ACCESSIBLE','ADD','ALL','ALTER','ANALYZE','AND','AS','ASC','ASENSITIVE','BEFORE','BETWEEN','BIGINT','BINARY','BLOB','BOTH','BY','CALL','CASCADE','CASE','CHANGE','CHAR','CHARACTER','CHECK','COLLATE','COLUMN','CONDITION','CONSTRAINT','CONTINUE','CONVERT','CREATE','CROSS','CURRENT_DATE','CURRENT_TIME','CURRENT_TIMESTAMP','CURRENT_USER','CURSOR','DATABASE','DATABASES','DAY_HOUR','DAY_MICROSECOND','DAY_MINUTE','DAY_SECOND','DEC','DECIMAL','DECLARE','DEFAULT','DELAYED','DELETE','DESC','DESCRIBE','DETERMINISTIC','DISTINCT','DISTINCTROW','DIV','DOUBLE','DROP','DUAL','EACH','ELSE','ELSEIF','ENCLOSED','ESCAPED','EXISTS','EXIT','EXPLAIN','FALSE','FETCH','FLOAT','FLOAT4','FLOAT8','FOR','FORCE','FOREIGN','FROM','FULLTEXT','GENERAL','GRANT','GROUP','HAVING','HIGH_PRIORITY','HOUR_MICROSECOND','HOUR_MINUTE','HOUR_SECOND','IF','IGNORE','IGNORE_SERVER_IDS','IN','INDEX','INFILE','INNER','INOUT','INSENSITIVE','INSERT','INT','INT1','INT2','INT3','INT4','INT8','INTEGER','INTERVAL','INTO','IS','ITERATE','JOIN','KEY','KEYS','KILL','LEADING','LEAVE','LEFT','LIKE','LIMIT','LINEAR','LINES','LOAD','LOCALTIME','LOCALTIMESTAMP','LOCK','LONG','LONGBLOB','LONGTEXT','LOOP','LOW_PRIORITY','MASTER_HEARTBEAT_PERIOD','MASTER_SSL_VERIFY_SERVER_CERT','MATCH','MAXVALUE','MEDIUMBLOB','MEDIUMINT','MEDIUMTEXT','MIDDLEINT','MINUTE_MICROSECOND','MINUTE_SECOND','MOD','MODIFIES','NATURAL','NOT','NO_WRITE_TO_BINLOG','NULL','NUMERIC','ON','OPTIMIZE','OPTION','OPTIONALLY','OR','ORDER','OUT','OUTER','OUTFILE','PARTITION','PRECISION','PRIMARY','PROCEDURE','PURGE','RANGE','READ','READS','READ_WRITE','REAL','RECURSIVE','REFERENCES','REGEXP','RELEASE','RENAME','REPEAT','REPLACE','REQUIRE','RESIGNAL','RESTRICT','RETURN','REVOKE','RIGHT','RLIKE','ROWS','SCHEMA','SCHEMAS','SECOND_MICROSECOND','SELECT','SENSITIVE','SEPARATOR','SET','SHOW','SIGNAL','SLOW','SMALLINT','SPATIAL','SPECIFIC','SQL','SQLEXCEPTION','SQLSTATE','SQLWARNING','SQL_BIG_RESULT','SQL_CALC_FOUND_ROWS','SQL_SMALL_RESULT','SSL','STARTING','STRAIGHT_JOIN','TABLE','TERMINATED','THEN','TINYBLOB','TINYINT','TINYTEXT','TO','TRAILING','TRIGGER','TRUE','UNDO','UNION','UNIQUE','UNLOCK','UNSIGNED','UPDATE','USAGE','USE','USING','UTC_DATE','UTC_TIME','UTC_TIMESTAMP','VALUES','VARBINARY','VARCHAR','VARCHARACTER','VARYING','WHEN','WHERE','WHILE','WITH','WRITE','XOR','YEAR_MONTH','ZEROFILL'];
    $mdbExceptions=['ACTION','BIT','DATE','ENUM','NO','TEXT','TIME','TIMESTAMP'];

    $stmt=$pdo->prepare('SELECT UPPER(TABLE_NAME) tn, UPPER(COLUMN_NAME) cn from information_schema.columns WHERE table_schema = ?');
    $stmt->execute([$_POST['database']]);
    while($rs=$stmt->fetch()) {
        if(in_array($rs->tn,$reserved)) {
            $error['tableHelper'][]=$rs->tn;
        }
        if(in_array($rs->cn,$reserved) && !in_array($rs->cn,$error['columnHelper'])) {
            $error['columnHelper'][]=$rs->cn;
        }
        if(in_array($rs->tn,$mdbReserved)) {
            $error['tableMdbReserved'][]=$rs->tn;
        }
        if(in_array($rs->cn,$mdbReserved) && !in_array($rs->cn,$error['columnMdbReserved'])) {
            $error['columnMdbReserved'][]=$rs->cn;
        }
        if(in_array($rs->tn,$mdbExceptions)) {
            $error['tableMdbException'][]=$rs->tn;
        }
        if(in_array($rs->cn,$mdbExceptions) && !in_array($rs->cn,$error['columnMdbException'])) {
            $error['columnMdbException'][]=$rs->cn;
        }
    }
    echo('<pre>'.print_r($error,1).'</pre>');
}
else {
    echo <<<EOT
<form method="post">
  Database Name: <input type="text" name="database"><br>
  <input type="submit">
</form>
EOT;
}

输出:

Array
(
    [tableHelper] => Array
        (
        )

    [columnHelper] => Array
        (
            [0] => TYPE
            [1] => NAME
            [2] => TIMESTAMP
            [3] => OFFSET
            [4] => VALUE
            [5] => STATUS
            [6] => PORT
        )

    [tableMdbReserved] => Array
        (
        )

    [columnMdbReserved] => Array
        (
            [0] => MAXVALUE
        )

    [tableMdbException] => Array
        (
        )

    [columnMdbException] => Array
        (
            [0] => TIMESTAMP
        )

)