2011-10-14 4 views
3

Comment puis-je construire une requête en fonction des paramètres que je reçois? Je veux ajouter à la fin de la requête.Joindre 2 chaînes en tant que requête dans une procédure

J'ai essayé quelque chose comme ça, mais il ne fonctionne pas:

DELIMITER $$ 
CREATE PROCEDURE `get_users`(IN sortstring TEXT) 
BEGIN 
PREPARE statement FROM 
"SELECT username, password FROM users ?"; 
SET @param = sortstring; 
EXECUTE statement USING @param; 
END$$ 

Et je passerais à sortstring quelque chose comme:

ORDER BY username DESC 

Puis-je faire plus simple en utilisant concat ou quelque chose?

+1

Je dois courir, mais regardez ici: http://forums.mysql.com/read.php?60,41372,47813 – MatBailie

+0

@Dems Merci. Pouvez-vous faire un post pour que je puisse le marquer comme la bonne réponse. – Monokh

+0

Assurez-vous que vous savez ce que "injection SQL" est lorsque vous utilisez un code comme celui-ci. –

Répondre

2

Vous devez déconstruire la chaîne de tri et vérifier toutes ses parties par rapport à une liste blanche des termes autorisés.

Voir le pseudo-code suivant. Je ne l'ai pas entièrement testé, mais disons que c'est l'idée qui compte.

DELIMITER $$ 

CREATE PROCEDURE `get_users`(IN sortstring TEXT) 
BEGIN 
    //check sortstring against a whitelist of allowed sortstrings 
    DECLARE sortpart VARCHAR(255); 
    DECLARE done BOOLEAN DEFAULT false; 
    DECLARE allok BOOLEAN DEFAULT true; 
    DECLARE i INTEGER DEFAULT 1; 

    WHILE ((NOT done) AND allOK) DO 
    SET sortpart = SUBSTRING_INDEX(sortstring,',',i); 
    SET i = i + 1; 
    SET done = (sortpart IS NULL); 
    IF NOT DONE THEN 
     SELECT 1 INTO allok WHERE EXISTS 
     (SELECT 1 FROM whitelist 
     WHERE allowed_sort_claused = sortpart AND tablename = 'users'); 
    END IF 
    END WHILE; 
    IF allOK THEN  
    PREPARE statement FROM 
     CONCAT('SELECT username, passhashwithsalt FROM users ',sortstring); 
    EXECUTE statement; 
    DEALLOCATE PREPARE statement; 
    ELSE SELECT 'error' as username, 'error' as passhashwithsalt; 
    END IF; 

END$$ 

Voir: How to prevent SQL injection with dynamic tablenames?

L'erreur dans votre code
Vous ne pouvez pas utiliser columnNames ou SQL-mots-clés en tant que paramètres. Vous ne pouvez utiliser que des valeurs en tant que paramètres. Pour cette raison, votre requête ne passera jamais préparer.
Le ? en SELECT x FROM t1 ? sera simplement remplacé par SELECT x FROM t1 'ORDER BY field1, field2' Ce qui n'a aucun sens.

Questions connexes