Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Apakah ada cara bagi PHP untuk memvalidasi sintaks SQL tanpa menjalankannya?

Dari MySQL 5.6.3 aktif, Anda dapat menggunakan EXPLAIN untuk sebagian besar kueri

Saya membuat ini dan berhasil dengan baik:

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

Ini akan mengembalikan False jika de query OK (multiple; pernyataan terpisah diperbolehkan), atau pesan kesalahan yang menyatakan kesalahan jika ada sintaks atau MySQL lainnya lainnya (seperti tabel atau kolom yang tidak ada).

Fiddle PHP

BUGS DIKENAL:

  • Kesalahan MySQL dengan nomor linen:nomor linen sebagian besar tidak cocok.
  • Tidak berfungsi untuk pernyataan MySQL selain 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. Bagaimana cara meneruskan daftar ID ke prosedur tersimpan MySQL?

  2. Kecualikan nilai tertentu saat membagi nilai tetap ke negara berdasarkan bagi hasil harian

  3. Menghubungkan tabel bersama antara dua model di Cakephp

  4. Data MySQL ke Tabel HTML bergaya

  5. Bagaimana cara memperbarui dua tabel dalam satu pernyataan?