Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Câu lệnh chuẩn bị sẵn trong thủ tục lưu trữ MySQL (SQL động) được tham số hóa

EXECUTE câu lệnh phải được cung cấp một danh sách cố định các đối số, vì vậy bạn sẽ phải chuẩn bị thực hiện câu lệnh trong IF / THEN / ELSE khối.

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;

Tôi không biết bất kỳ cách nào để giải quyết vấn đề này trong phạm vi giới hạn của ngôn ngữ thủ tục được lưu trữ MySQL. Đối với tôi, đó là một lý do chính đáng khác để không sử dụng SQL động trong các thủ tục được lưu trữ.

Re nhận xét của bạn:

Tôi hiểu rồi ... bạn có thể sử dụng CASE tuyên bố thay vì IF / THEN / ELSE , nhưng bạn thực sự có 2 =128 trường hợp khác nhau có thể xảy ra cho các chuỗi truy vấn, bởi vì tôi cho rằng bất kỳ mô-đun nào trong số 7 mô-đun đó đều có thể được tìm kiếm hoặc không.

Một giải pháp thay thế cho phép bạn sử dụng các tham số truy vấn là quên sử dụng UNION và thay vào đó, hãy viết thủ tục theo cách chạy tối đa 7 SELECT riêng biệt truy vấn và trả về tất cả chúng dưới dạng nhiều bộ kết quả . Đó là một cái gì đó mà các thủ tục được lưu trữ nhằm mục đích làm. Nhưng bạn phải viết mã trong lớp PHP của mình để lần lượt tìm nạp từng tập kết quả. Đó là, lặp qua các tập kết quả và trong vòng lặp đó, lặp qua các hàng của tập kết quả hiện tại. Xem ví dụ tại PDO ::nextRowset () hoặc mysqli ::next_result () .

Không, bạn sẽ không an toàn nếu làm vậy! Sử dụng tham số truy vấn trong PHP để chuyển một chuỗi tới CALL WEBSITE_mainSearch (?) là vô ích để bảo vệ chống lại việc tiêm SQL, nếu sau đó bạn nối giá trị tham số đó vào một chuỗi khác bên trong thủ tục và thực hiện phân tích cú pháp và thực thi SQL động. Việc sử dụng các tham số truy vấn không làm cho các giá trị tham số trở nên "an toàn", chúng chỉ tách các giá trị đó khỏi giai đoạn phân tích cú pháp SQL.

Bạn sẽ an toàn hơn nếu sử dụng hàm tích hợp sẵn của MySQL QUOTE () khi nối các chuỗi. QUOTE () thoát các ký tự đặc biệt, giống như mysql_real_escape_string () . Ngoại trừ nó hơi khác một chút, vì nó cũng tạo ra các dấu nháy đơn phân cách chuỗi, như PDO ::quote () không.

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),')') ;

Cập nhật:một giải pháp thay thế khác:sử dụng UNION để thêm nhiều truy vấn con hơn và giữ số lượng mô-đun. Sau đó, sử dụng CASE để thực hiện truy vấn đã chuẩn bị với một số tham số khác nhau dựa trên tổng số tích lũy.

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. Lưu trữ tên người dùng và mật khẩu trong cơ sở dữ liệu có an toàn không?

  2. Khối lượng công việc kết hợp cơ sở dữ liệu OLTP / Analytics:Sao chép dữ liệu MySQL sang ClickHouse

  3. Cách lấy tên và tên người quản lý

  4. khởi tạo mysql bằng cách sử dụng hàm windows api CreateProcessA

  5. XÓA truy vấn với WHERE TỒN TẠI trong MySQL