Comment construire dynamique de la requête par les paramètres de liaison du nœud.js-sql?
Je suis en utilisant nodejs-mysql
module de requête dans node.js récemment, et dans mon cas je ne pouvais utiliser le paramètre-syntaxe de liaison comme:
SELECT * FROM table WHERE name = ?
Maintenant, je veux construire sql dynamique avec ces ?
OU ??
paramètres. Supposons que j'ai 2 conditions(name
et age
) dont l'un d'eux pourrait être null (si l'utilisateur ne fournit pas elle),
Je tiens donc à construire MySQL dans 3 cas:
- seulement
name=Bob
:SELECT * FROM table WHERE name = 'Bob'
- seulement
age=40
:SELECT * FROM table WHERE age > 40
- à la fois:
SELECT * FROM table WHERE name = 'Bob' AND age > 40
Je sais que c'est facile si vous créez la requête sur votre propre, mais comment puis-je obtenir lors de l'utilisation des espaces réservés qui ne peuvent lier le terrain ou des valeurs ?
Dans le document de nodejs-mysql
, espace réservé ?
que se de valeurs et d' ??
stands pour les champs:
- https://github.com/felixge/node-mysql/#escaping-query-values
- https://github.com/felixge/node-mysql/#escaping-query-identifiers
Ma première pensée de la solution consiste à insérer une requête pièce par l'utilisation de ces espaces réservés, mais il s'agit à l'échec, car les deux ?
et ??
échappera à ma requête pièce, et ma requête sera exécutée de manière incorrecte.
Mon code pour l'instant est comme ci-dessous, dont je suis defenitly sûr que c'est pas correct, car la requête morceau a été échappé:
//achieve paramters from url request
var condition = {};
if(params.name)condition["name"] = ["LIKE", "%" + params.name + "%"];
if(params.age)condition["age"] = parseInt(params.age, 10);
//build query
var sqlPiece = buildQuery(condition);
//try to replace ? with query
var sql = 'SELECT * FROM table WHERE ?';
connection.query(sql, sqlPiece, function(err, results) {
//do things
});
//my own query build function to proceed conditions
function buildQuery(condition) {
var conditionArray = [];
for(var field in condition){
var con = condition[field];
if(con !== undefined){
field = arguments[1] ? arguments[1] + "." + field : field;
var subCondition;
if(con instanceof Array) {
subCondition = field + " " + con[0] + " " + wrapString(con[1]);
}else{
subCondition = field + " = " + wrapString(con);
}
conditionArray.push(subCondition);
}
}
return conditionArray.length > 0 ? conditionArray.join(" AND ") : "1";
}
//wrap string value
function wrapString(value){
return typeof value === "string" ? "'" + value + "'" : value;
}
Donc est-il possible que je peux résoudre ce problème?
Mise à jour
Grâce à la Jordanie de l'Offre, ça fonctionne, mais :
Je sais que la construction de la requête par la chaîne concat est très bon, mais dans mon cas, je ne peux pas l'utiliser, parce que je suis en utilisant certains middleware ou la poignée de mysql et contrôleur, donc ce que je peux faire est de définir interface, qui est une chaîne sql avec des espaces réservés. Ainsi, l'interface de chaîne est prédéfini avant, et je ne peux pas le modifier au cours de ma fonction de contrôleur.
OriginalL'auteur Bandon | 2015-08-05
Vous devez vous connecter pour publier un commentaire.
Vous êtes hors d'un bon début, mais vous avez pu avoir à y penser un peu. L'astuce consiste à créer une requête avec des espaces réservés (
?
) comme une chaîne de caractères et simultanément de construire un tableau de valeurs.Donc, si vous avez
params = { name: 'foo', age: 40 }
, vous voulez construire les objets suivants:Si vous n'avez
{ name: 'foo' }
, vous allez construire ces à la place:De toute façon, vous pouvez utiliser ces objets directement dans le
query
méthode, c'est à dire:Comment construire ces objets, alors? En fait, le code est très similaire à votre
buildQuery
fonction, mais moins complexe.Il n'est pas clair ce que tu veux dire par "interface". Pouvez-vous montrer un peu de code? nœud-mysql espaces réservés sont pour échapper à des champs et des valeurs, et vous n'allez pas être en mesure de les faire travailler pour les plus grandes chaînes SQL. Si vous voulez des fonctionnalités similaires, mais sans échapper, je vous suggère d'utiliser un sprintf de mise en œuvre de comme sprintf.js.
Oui j'ai utilisé un middleware, et ce que je peux faire est de définir un .fichier json qui décrivent les interfaces, comme : "sql: SELECT * from table where ...?...??", C'est corrigé et sera chargé lorsque c'est paraphe, afin que je puisse l'insérer quelques pièces sql
OriginalL'auteur Jordan Running