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

PHPがSQL構文を実行せずに検証する方法はありますか?

    MySQL 5.6.3以降では、ほとんどのクエリにEXPLAINを使用できます

    私はこれを作りました、そしてそれは素敵に働きます:

    function checkMySqlSyntax($mysqli, $query) {
       if ( trim($query) ) {
          // Replace characters within string literals that may *** up the process
          $query = replaceCharacterWithinQuotes($query, '#', '%') ;
          $query = replaceCharacterWithinQuotes($query, ';', ':') ;
          // Prepare the query to make a valid EXPLAIN query
          // Remove comments # comment ; or  # comment newline
          // Remove SET @var=val;
          // Remove empty statements
          // Remove last ;
          // Put EXPLAIN in front of every MySQL statement (separated by ;) 
          $query = "EXPLAIN " .
                   preg_replace(Array("/#[^\n\r;]*([\n\r;]|$)/",
                                  "/[Ss][Ee][Tt]\s+\@[A-Za-z0-9_]+\s*:?=\s*[^;]+(;|$)/",
                                  "/;\s*;/",
                                  "/;\s*$/",
                                  "/;/"),
                            Array("","", ";","", "; EXPLAIN "), $query) ;
    
          foreach(explode(';', $query) as $q) {
             $result = $mysqli->query($q) ;
             $err = !$result ? $mysqli->error : false ;
             if ( ! is_object($result) && ! $err ) $err = "Unknown SQL error";
             if ( $err) return $err ;
          }
          return false ;
      }
    }
    
    function replaceCharacterWithinQuotes($str, $char, $repl) {
        if ( strpos( $str, $char ) === false ) return $str ;
    
        $placeholder = chr(7) ;
        $inSingleQuote = false ;
        $inDoubleQuotes = false ;
        for ( $p = 0 ; $p < strlen($str) ; $p++ ) {
            switch ( $str[$p] ) {
                case "'": if ( ! $inDoubleQuotes ) $inSingleQuote = ! $inSingleQuote ; break ;
                case '"': if ( ! $inSingleQuote ) $inDoubleQuotes = ! $inDoubleQuotes ; break ;
                case '\\': $p++ ; break ;
                case $char: if ( $inSingleQuote || $inDoubleQuotes) $str[$p] = $placeholder ; break ;
            }
        }
        return str_replace($placeholder, $repl, $str) ;
     }
    

    クエリがOKの場合はFalseを返し(複数の;個別のステートメントを許可)、構文または他のMySQL(存在しないテーブルや列など)がある場合はエラーを示すエラーメッセージを返します。

    PHPフィドル

    既知のバグ:

    • 行番号に関するMySQLエラー:行番号はほとんど一致しません。
    • SELECT、UPDATE、REPLACE、INSERT、DELETE以外のMySQLステートメントでは機能しません


    1. Laravel4カスケードソフト削除

    2. 2つのODBCデータソースでのOracle®異種サービスの使用

    3. JDBC接続のネットワークタイムアウトの設定

    4. SQL Serverで「datetime」を「time」に変換する(T-SQLの例)