Le code de la requête et la requête:
ps = conn.prepareStatement("select instance_id, ? from eam_measurement where resource_id in (select RESOURCE_ID from eam_res_grp_res_map where resource_group_id = ?) and DSN like '?' order by 2");
ps.setString(1,"SUBSTR(DSN,27,16)");
ps.setInt(2,defaultWasGroup);
ps.setString(3,"%Module=jvmRuntimeModule:freeMemory%");
rs = ps.executeQuery();
while (rs.next()) { bla blah blah blah ...
Retourne une ResultSet
vide.
Grâce au débogage de base, j’ai trouvé la troisième liaison, c’est-à-dire le problème.
DSN like '?'
J'ai essayé toutes sortes de variations, dont la plus sensée semblait utiliser:
DSN like concat('%',?,'%')
mais cela ne fonctionne pas car il me manque le '
de part et d'autre de la chaîne concaténée alors j'essaie:
DSN like ' concat('%',Module=P_STAG_JDBC01:poolSize,'%') ' order by 2
mais je n'arrive tout simplement pas à trouver un moyen de les intégrer qui fonctionne.
Qu'est-ce que je rate?
Votre déclaration pose deux problèmes. Vous devez comprendre comment fonctionnent les variables de liaison. La requête est non traitée en substituant les caractères ?
par vos paramètres. Au lieu de cela, l'instruction est compilée avec des espaces réservés puis, lors de l'exécution, les valeurs réelles des paramètres sont transmises au DB.
En d'autres termes, vous analysez la requête suivante:
SELECT instance_id, :p1
FROM eam_measurement
WHERE resource_id IN (SELECT RESOURCE_ID
FROM eam_res_grp_res_map
WHERE resource_group_id = :p2)
AND DSN LIKE '?'
ORDER BY 2
Je suis sûr que le dernier paramètre sera ignoré car il s'agit d'une chaîne de caractères délimitée. Même s'il n'est pas ignoré, il n'est pas logique d'avoir des caractères '
car Oracle ne liera pas de paramètre dans une chaîne (je suis surpris qu'il n'ait pas généré d'erreur, interceptez-vous des exceptions?).
Maintenant, si vous remplacez votre DNS LIKE '?'
par DSN LIKE ?
et que vous liez "%Module=jvmRuntimeModule:freeMemory%"
, cela aura du sens et devrait renvoyer les lignes correctes.
Vous avez toujours le problème avec votre premier paramètre, il ne fera pas ce que vous attendez, car la requête qui sera exécutée sera équivalente à la requête suivante:
SELECT instance_id, 'SUBSTR(DSN,27,16)'
FROM ...
qui n'est pas du tout la même chose que
SELECT instance_id, SUBSTR(DSN,27,16)
FROM ...
Je suggérerais d'analyser (= prepareStatement) la requête suivante si vous vous attendez à ce que SUBSTR soit dynamique:
SELECT instance_id, SUBSTR(DSN,?,?)
FROM eam_measurement
WHERE resource_id IN (SELECT RESOURCE_ID
FROM eam_res_grp_res_map
WHERE resource_group_id = ?)
AND DSN LIKE ?
ORDER BY 2
Omettez le '
autour du ?
. Sans le '
, ?
est un espace réservé pour un paramètre. Avec lui, il s’agit d’une chaîne SQL (identique à "?"
en Java).
Ensuite, vous devez concaténer la chaîne du côté Java; vous ne pouvez pas transmettre de fonctions SQL en tant que paramètres de requêtes; uniquement des valeurs de base (telles que chaîne, entier, etc.), car le pilote JDBC convertit le paramètre en type SQL attendu par la base de données et ne peut pas exécuter les fonctions SQL à cette étape.
PreparedStatement ps = con.prepareStatement(
"select columname from tablename where LOWER(columnname) LIKE LOWER('"+var+"%')");
Ici var
est la variable dans laquelle la valeur à rechercher est stockée ...
Tu peux essayer:
String beforeAndAfter = "%" + yourVariable + "%";