Pas une alternative exacte à MySQL FIND_IN_SET
, mais dans votre exemple (où vous avez seulement besoin de savoir si une valeur est contenue dans un ensemble séparé par des virgules) Oracle REGEX_COUNT
avec la regex '^([^,]+,)*your_value(,[^,]+)*$'
conviendra.
Examinez les requêtes SQL suivantes (pour Oracle)...
Exemples avec des chiffres
Rechercher le numéro 1
dans l'ensemble :[1,2,3,4,5,6,11,12,13]
SELECT
CASE WHEN REGEXP_COUNT('1,2,3,4,5,6,11,12,13', '^([^,]+,)*1(,[^,]+)*$', 1, 'i') > 0
THEN 1 ELSE 0
END AS cnt
FROM DUAL;
Renvoie 1
correctement
Rechercher le numéro 1
dans l'ensemble :[111,222,333]. INSTR ne parviendrait pas à signaler un résultat négatif dans ce cas.
SELECT
CASE WHEN REGEXP_COUNT('111,222,333', '^([^,]+,)*1(,[^,]+)*$', 1, 'i') > 0
THEN 1 ELSE 0
END AS cnt
FROM DUAL;
Renvoie 0
correctement
Exemples avec des chaînes
Rechercher 'John'
dans un ensemble de noms :
SELECT
CASE WHEN REGEXP_COUNT('john,peter,jim,kelly,laura,bill,tom,foo,bar', '^([^,]+,)*John(,[^,]+)*$', 1, 'i') > 0
THEN 1 ELSE 0
END as cnt
FROM DUAL;
Renvoie 1
correctement
Mais si vous recherchez la lettre 'a'
, il renverra correctement zéro (INSTR échouerait à nouveau).
SELECT
CASE WHEN REGEXP_COUNT('john,peter,jim,kelly,laura,bill,tom,foo,bar', '^([^,]+,)*a(,[^,]+)*$', 1, 'i') > 0
THEN 1 ELSE 0
END as cnt
FROM DUAL;
Renvoie 0
correctement
Je sais que cette question a reçu une réponse il y a longtemps, mais elle se classe bien dans les résultats de recherche et pourrait probablement aider les autres qui recherchent une solution simple mais plus correcte que INSTR
d'Oracle fonction.
Expressions booléennes
Il est également possible d'utiliser des expressions booléennes, comme OR
ou AND
.
Un exemple utilisant OR
est le suivant :
SELECT
CASE WHEN REGEXP_COUNT('john,peter,jim,kelly,laura,bill,tom,foo,bar', '^([^,]+,)*(helen|peter)(,[^,]+)*$', 1, 'i') > 0
THEN 1 ELSE 0
END as cnt
FROM DUAL;
Renvoie 1
correctement, car il a trouvé "peter" (recherchez soit "helen" ou "pierre" ).
Pour AND
l'approche est un peu différente (modifie l'expression CASE au lieu de la regex ):
SELECT
CASE WHEN
REGEXP_COUNT('john,peter,jim,kelly,laura,bill,tom,foo,bar', '^([^,]+,)*john(,[^,]+)*$', 1, 'i') > 0 AND
REGEXP_COUNT('john,peter,jim,kelly,laura,bill,tom,foo,bar', '^([^,]+,)*peter(,[^,]+)*$', 1, 'i') > 0
THEN 1 ELSE 0
END as cnt
FROM DUAL;
La requête ci-dessus recherche à la fois "john" ET "Pierre" . Le AND
l'opération peut être mise en œuvre facilement en dupliquant le REGEXP_COUNT
expression dans le CASE
syntaxe, mais en retour avec une petite pénalité de performance.