Je reçois un tableau du front-end pour effectuer des filtres en fonction de cela à l'intérieur de la requête SQL.
Je veux appliquer un filtre LIKE
sur le tableau. Comment ajouter un tableau dans la fonction LIKE
?
J'utilise Angular avec Html comme frontal et Node comme back-end.
Tableau transmis depuis le frontal:
SELECT * FROM Skills WHERE Description LIKE ('%Sports%') SELECT * FROM Skills WHERE Description LIKE ('%Life%') SELECT * FROM Skills WHERE Description LIKE ('%Relationship%')
La requête SQL est:
[ "Sports", "Life", "Relationship", ...]
Mais j'obtiens un tableau du front-end - comment créer une requête pour cela?
3 Réponses :
À titre d'exemple, pour SQL Server 2016+ et STRING_SPLIT()
:
Select * from Skills WHERE ( Description Like '%Sports%' OR Description Like '%Life%' OR Description Like '%Life%' )
Il convient de mentionner que les données d'entrée doivent être strictement contrôlées, car une telle méthode peut mener à une attaque par injection SQL
En tant qu'approche alternative, plus sûre et plus simple: SQL peut être généré côté application de cette façon:
DECLARE @Str NVARCHAR(100) = N'mast;mode' SELECT name FROM sys.databases sd INNER JOIN STRING_SPLIT(@Str, N';') val ON sd.name LIKE N'%' + val.value + N'%' -- returns: name ------ master model
STRING_SPLIT est un objet invalide dans mon cas. J'utilise SQL Server 2017
@AmandeepSingh, le niveau de compatibilité d'une base de données défini sur SQL 2014 ou inférieur, il doit être défini sur au moins SQL2016
pouvons-nous utiliser STRING_SPLIT sans jointure?
@AmandeepSingh, pas avec l'instruction LIKE
. Veuillez noter que j'ai ajouté une approche alternative, qui n'utilise aucune jointure, peut-être que cela peut être une meilleure alternative pour votre cas
Pourquoi voulez-vous éviter d'utiliser une jointure? Vous pouvez le faire sans jointure, mais cela devient beaucoup plus ridicule.
Dans SQL Server 2017, vous pouvez utiliser OPENJSON
pour consommer la chaîne JSON telle quelle:
SELECT * FROM skills WHERE EXISTS ( SELECT 1 FROM OPENJSON('["Sports", "Life", "Relationship"]', '$') AS j WHERE skills.description LIKE '%' + j.value + '%' )
Je fais aussi comme ça. Mais le problème est que le tableau provenant du front-end est ["Sports", "Life"] et l'erreur de SQL est que le texte JSON n'est pas correctement formaté. Le caractère inattendu '' 'est trouvé à la position 1.' ''
Vous passez évidemment des json invalides. Peut-être avez-vous des citations supplémentaires.
C'est impossible à dire. Mais peut-être que si vous utilisez des paramètres, vous feriez ... FROM OPENJSON (@ p1, '$') AS ...
et la valeur de @ p1
serait < code> JSON.stringify (that_array)
Un simple appel map ()
sur le tableau words
vous permettra de générer les requêtes correspondantes, que vous pourrez ensuite exécuter (avec ou sans les joindre d'abord dans une seule chaîne).
Démo:
var words = ["Sports", "Life", "Relationship"]; var template = "Select * From Skills Where Description Like ('%{0}%')"; var queries = words.map(word => template.replace('{0}', word)); var combinedQuery = queries.join("\r\n"); console.log(queries); console.log(combinedQuery);
Vous devez ajouter plusieurs mots en utilisant ou
, c'est-à-dire que la requête ressemblerait à WHERE col comme '% life%' ou col comme '% sports%'
etc.
Telle est votre hypothèse, OP ne le mentionne pas du tout.
Passez un paramètre de table. docs.microsoft.com/en-us/sql/relational-databases/tables/... Cela devient alors trivial.
Quel langage de programmation utilisez-vous sur le backend. Je suis sûr que vous en utilisez un.
@SalmanA J'utilise Node JS comme backend.
Vous pouvez analyser le JSON dans Node et générer une requête qui utilise des paires de valeurs de table. Si vous utilisez SQL 2016+, il existe également une option plus simple.
Sachez également que puisque vous utilisez des caractères génériques de premier plan, vous avez rendu votre requête nonSARGable et tous les index sont infructueux dans la colonne Description.