sql >> Database teknologi >  >> RDS >> Mysql

MySQL Stored Procedure Prepared Statement (dynamisk SQL) Parametriseret

EXECUTE sætningen skal have en fast liste over argumenter, så du bliver nødt til at forberede og udfør sætningen i en IF/THEN/ELSE blokere.

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;

Jeg kender ikke nogen måde at løse dette på i det begrænsede omfang af MySQL-lagrede proceduresprog. For mig er det endnu en god grund til ikke at bruge dynamisk SQL i lagrede procedurer.

Om dine kommentarer:

Jeg kan se... du kunne bruge en CASE erklæring i stedet for en IF/THEN/ELSE , men du har faktisk 2 =128 potentielle forskellige tilfælde for forespørgselsstrenge, fordi jeg antager, at alle disse 7 moduler enten kan søges eller ej.

Et alternativ, der ville tillade dig at bruge forespørgselsparametre, er at glemme alt om at bruge UNION , og skriv i stedet proceduren på en sådan måde, at den kører op til 7 separate SELECT forespørgsler og returnerer dem alle som flere resultatsæt . Det er noget, lagrede procedurer er beregnet til at gøre. Men du skal skrive kode i dit PHP-lag for at hente hvert resultatsæt efter tur. Det vil sige, sløjfe over resultatsættene, og inden for denne sløjfe, sløjfe over rækkerne i det aktuelle resultatsæt. Se eksempel på PDO::nextRowset() eller mysqli::next_result() .

Nej, du er ikke sikker, hvis du gør det! Brug af en forespørgselsparameter i PHP til at sende en streng til CALL WEBSITE_mainSearch(?) er ubrugelig til at beskytte mod SQL-injektion, hvis du derefter sammenkæder denne parameterværdi i en anden streng inde i proceduren og laver en dynamisk SQL parse-and-execute. Brug af forespørgselsparametre gør ikke parameterværdier "sikre", de adskiller blot disse værdier fra SQL-parsefasen.

Du er mere sikker, hvis du bruger MySQL's indbyggede funktion CITAT() ved sammenkædning af strengene. QUOTE() gør escape af specialtegn, ligesom mysql_real_escape_string() . Bortset fra, at det er lidt anderledes, fordi det også producerer de enkelte anførselstegn, der afgrænser strengen, såsom PDO::quote() gør.

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

Opdatering:endnu et alternativ:brug UNION for at tilføje flere underforespørgsler og holde optælling af modulerne. Brug derefter en CASE for at udføre den forberedte forespørgsel med et andet antal parametre baseret på det akkumulerede antal.

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. Oracles standard DATO-format

  2. Indsættelse af afkrydsningsfeltværdier i MySQL-database med PHP

  3. Brug af StringWriter til XML-serialisering

  4. Hvordan ændrer jeg formateringen for mine returværdier i denne funktion?