sql >> Databáze >  >> RDS >> Mysql

MySQL Stored Procedure Připravený příkaz (Dynamic SQL) Parametrizován

EXECUTE příkaz musí mít pevný seznam argumentů, takže si budete muset připravit a proveďte příkaz v IF/THEN/ELSE blokovat.

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;

Neznám žádný způsob, jak to vyřešit v omezeném rozsahu jazyka uložených procedur MySQL. Pro mě je to další dobrý důvod, proč nepoužívat dynamické SQL v uložených procedurách.

K vašim komentářům:

Chápu... můžete použít CASE prohlášení místo IF/THEN/ELSE , ale ve skutečnosti máte 2 =128 potenciálních různých případů pro řetězce dotazů, protože předpokládám, že kterýkoli z těchto 7 modulů lze prohledat nebo ne.

Alternativou, která by vám umožnila používat parametry dotazu, je zapomenout na použití UNION a místo toho zapište proceduru tak, aby spustila až 7 samostatných SELECT dotazy a vrátí je všechny jako více sad výsledků . To je něco, co mají uložené procedury dělat. Ale musíte napsat kód ve vaší vrstvě PHP, abyste postupně získali každou sadu výsledků. To znamená, že smyčka přes výsledné sady a v rámci této smyčky smyčka přes řádky aktuální sady výsledků. Viz příklad na PDO::nextRowset() nebo mysqli::next_result() .

Ne, pokud to uděláte, nejste v bezpečí! Použití parametru dotazu v PHP k předání řetězce do CALL WEBSITE_mainSearch(?) je k ochraně před vložením SQL k ničemu, pokud pak zřetězíte hodnotu parametru do jiného řetězce uvnitř procedury a provedete dynamickou analýzu a provedení SQL. Použití parametrů dotazu nečiní hodnoty parametrů "bezpečnými", pouze oddělují tyto hodnoty od fáze analýzy SQL.

Jste ve větším bezpečí, pokud používáte vestavěnou funkci MySQL CITACE() při zřetězení strun. QUOTE() dělá escapování speciálních znaků, stejně jako mysql_real_escape_string() . Až na to, že je to trochu jiné, protože také vytváří jednoduché uvozovky vymezující řetězec, jako je PDO::quote() ano.

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

Aktualizace:ještě jedna alternativa:použijte UNION přidat další poddotazy a udržet počet modulů. Poté použijte CASE pro provedení připraveného dotazu s jiným počtem parametrů na základě akumulovaného počtu.

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. Zápis datového rámce do tabulky MySql DB

  2. parametrizovaný dotaz mysql v ASP.NET

  3. Zachyťte varování plánu provádění pomocí rozšířených událostí

  4. Které metody lze použít ke správě různých verzí již existujících databází?