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

Pernyataan Disiapkan Prosedur Tersimpan MySQL (SQL Dinamis) Berparameter

EXECUTE pernyataan harus diberikan daftar argumen yang tetap, jadi Anda harus menyiapkan dan jalankan pernyataan dalam IF/THEN/ELSE blokir.

IF articlesModule = 1 THEN
    SET @query = ... UNION ...
    PREPARE stmt FROM @query;
    EXECUTE stmt USING @searchWordIn, @searchWordIn, @searchWordIn, @searchWordIn;
ELSE
    SET @query = ...; /* no UNION */
    PREPARE stmt FROM @query;
    EXECUTE stmt USING @searchWordIn, @searchWordIn;
END IF;

Saya tidak tahu cara untuk menyelesaikan ini dalam lingkup terbatas bahasa prosedur tersimpan MySQL. Bagi saya, ini adalah alasan bagus lainnya untuk tidak menggunakan SQL dinamis dalam prosedur tersimpan.

Kembali komentar Anda:

Begitu... Anda bisa menggunakan CASE pernyataan bukannya IF/THEN/ELSE , tetapi Anda sebenarnya memiliki 2 =128 kemungkinan kasus berbeda untuk string kueri, karena saya menganggap salah satu dari 7 modul tersebut dapat ditelusuri atau tidak.

Alternatif yang memungkinkan Anda menggunakan parameter kueri adalah melupakan penggunaan UNION , dan sebagai gantinya tulis prosedur sedemikian rupa sehingga menjalankan hingga 7 SELECT . yang terpisah kueri dan mengembalikan semuanya sebagai beberapa kumpulan hasil . Itu adalah sesuatu yang dimaksudkan untuk dilakukan oleh prosedur tersimpan. Tetapi Anda harus menulis kode di lapisan PHP Anda untuk mengambil setiap hasil yang ditetapkan secara bergantian. Artinya, loop di atas set hasil, dan di dalam loop itu, loop di atas baris set hasil saat ini. Lihat contoh di PDO::nextRowset() atau mysqli::next_result() .

Tidak, Anda tidak aman jika melakukannya! Menggunakan parameter kueri di PHP untuk meneruskan string ke CALL WEBSITE_mainSearch(?) tidak berguna untuk melindungi dari injeksi SQL, jika Anda kemudian menggabungkan nilai parameter itu ke string lain di dalam prosedur dan melakukan parse-and-execute SQL dinamis. Menggunakan parameter kueri tidak membuat nilai parameter "aman", melainkan hanya memisahkan nilai tersebut dari fase penguraian SQL.

Anda lebih aman jika menggunakan fungsi bawaan MySQL KUTIPAN() saat menggabungkan string. QUOTE() tidak keluar dari karakter khusus, seperti mysql_real_escape_string() . Kecuali itu sedikit berbeda, karena itu juga menghasilkan tanda kutip tunggal yang membatasi string, seperti PDO::quote() tidak.

SET @query = CONCAT(@query, 'SELECT blockName AS itemName, blockPath AS seoName, 
  blockID AS itemID, MATCH(blockName, blockBody) AGAINST (',
  QUOTE(searchWordIn), ') AS relevance, \'block\' AS itemType 
  FROM content_blocks WHERE MATCH(blockName, blockBody) AGAINST (',
  QUOTE(searchWordIn),')') ;

Pembaruan:satu alternatif lagi:gunakan UNION untuk menambahkan lebih banyak subkueri, dan menghitung jumlah modul. Kemudian gunakan CASE untuk mengeksekusi kueri yang disiapkan dengan jumlah parameter yang berbeda berdasarkan jumlah akumulasi.

SET @n = 0;
IF articlesModule = 1 THEN
    SET @query = ... UNION ...
    SET @n = @n+1;
END IF;

IF newsModule = 1 THEN
    SET @query = ... UNION ...
    SET @n = @n+1;
END IF;

... and similar for the other 5 modules ...

PREPARE stmt FROM @query;

CASE @n
WHEN 1:
    EXECUTE stmt USING @searchWordIn, @searchWordIn;
WHEN 2:
    EXECUTE stmt USING @searchWordIn, @searchWordIn, @searchWordIn, @searchWordIn;
WHEN 3:
    EXECUTE stmt USING @searchWordIn, @searchWordIn, @searchWordIn, @searchWordIn,
      @searchWordIn, @searchWordIn;
WHEN 4:
    EXECUTE stmt USING @searchWordIn, @searchWordIn, @searchWordIn, @searchWordIn,
      @searchWordIn, @searchWordIn, @searchWordIn, @searchWordIn;
WHEN 5:
    EXECUTE stmt USING @searchWordIn, @searchWordIn, @searchWordIn, @searchWordIn,
      @searchWordIn, @searchWordIn, @searchWordIn, @searchWordIn,
      @searchWordIn, @searchWordIn;
WHEN 6:
    EXECUTE stmt USING @searchWordIn, @searchWordIn, @searchWordIn, @searchWordIn,
      @searchWordIn, @searchWordIn, @searchWordIn, @searchWordIn,
      @searchWordIn, @searchWordIn, @searchWordIn, @searchWordIn;
WHEN 7:
    EXECUTE stmt USING @searchWordIn, @searchWordIn, @searchWordIn, @searchWordIn,
      @searchWordIn, @searchWordIn, @searchWordIn, @searchWordIn,
      @searchWordIn, @searchWordIn, @searchWordIn, @searchWordIn, 
      @searchWordIn, @searchWordIn;
END;



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Apakah sebaiknya menggunakan MySQL dan Neo4j bersama-sama?

  2. Struktur database MySql untuk :Cari berdasarkan kolom tunggal dan nilai yang berbeda

  3. Cara Instal MySQL dengan phpMyAdmin di Debian 7

  4. Bagaimana mencegah karakter aneh muncul di halaman web

  5. Hitung baris di mysql berdasarkan grup