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

Czy PHP może sprawdzić poprawność składni SQL bez jej wykonywania?

Od MySQL 5.6.3 możesz używać EXPLAIN do większości zapytań

Zrobiłem to i działa cudownie:

Funkcja
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) ;
 }

Zwróci False, jeśli zapytanie jest OK (dozwolone jest wiele; rozdzielonych instrukcji) lub komunikat o błędzie, jeśli istnieje składnia lub inny MySQL (np. nieistniejąca tabela lub kolumna).

PHP Fiddle

ZNANE BŁĘDY:

  • Błędy MySQL z numerami bielizny:numery bielizny przeważnie się nie zgadzają.
  • Nie działa dla instrukcji MySQL innych niż SELECT, UPDATE, REPLACE, INSERT, DELETE


  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:Jak uzyskać wszystkie wiersze, które mają więcej niż określoną liczbę dziesiętną po kropce?

  2. wypełnienie wymaganej ilości za pomocą mysql

  3. Znajdowanie wolnych bloków czasu w mysql i php?

  4. Sprawdź, czy nazwa użytkownika już istnieje przy użyciu PHP

  5. UNIKALNE Ograniczenie, tylko gdy pole zawiera określoną wartość