java - utilisation - Vous ne pouvez pas utiliser une requête LIKE dans un JDBC PreparedStatement?




utilisation de preparedstatement java (5)

Cela devrait fonctionner:

"\'" + "?" + "\'"

Le code de 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 un ResultSet vide.

Grâce au débogage de base, j'ai trouvé que c'était le troisième problème, c'est-à-dire

DSN like '?'

J'ai essayé toutes sortes de variations, les plus sensibles semblant utiliser:

DSN like concat('%',?,'%')

mais cela ne fonctionne pas car je manque le ' de chaque côté de la chaîne concaténée, alors j'essaye:

DSN like ' concat('%',Module=P_STAG_JDBC01:poolSize,'%') ' order by 2

mais je ne peux tout simplement pas trouver un moyen de les intégrer dans ce travail.

Qu'est-ce que je rate?


Il y a deux problèmes avec votre déclaration. Vous devez comprendre comment fonctionnent les variables liées. La requête n'est pas traitée en substituant les caractères ? avec vos paramètres. Au lieu de cela, l'instruction est compilée avec des espaces réservés, puis, pendant l'exécution, les valeurs réelles des paramètres sont données à la base de données.

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 se trouve dans une chaîne de caractères délimitée. Même s'il n'est pas ignoré, il est inutile de disposer ' caractères, car Oracle ne liera pas un paramètre dans une chaîne (je suis surpris qu'il n'ait pas commis d'erreur, attrapez-vous des exceptions?).

Maintenant, si vous remplacez votre DNS LIKE '?' avec DSN LIKE ? et lier "%Module=jvmRuntimeModule:freeMemory%" cela aura un sens et devrait retourner les lignes correctes.

Vous avez toujours le problème avec votre premier paramètre, il ne fera pas ce que vous attendez, c’est-à-dire que 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 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 le 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

Si vous souhaitez utiliser LIKE dans une instruction préparée et souhaitez également utiliser les caractères% dans LIKE;

écrire l'instruction préparée normalement ".... LIKE? ...." et en assignant la valeur du paramètre à l'utilisation du point d'interrogation

ps.setString(1, "%" + "your string value" + "%");

Cela fonctionnera :)


Tout d'abord, les espaces réservés PreparedStatement (ceux ?? ) Ne concernent que les valeurs de colonne , pas les noms de table, les noms de colonne, les fonctions / clauses SQL, etc. Mieux vaut utiliser String#format() place. Deuxièmement, vous ne devriez pas citer les espaces réservés comme '?' , il ne ferait que malformer la requête finale. Les créateurs de PreparedStatement effectuent déjà le travail de citation (et d’échappement) pour vous.

Voici le SQL fixe:

private static final String SQL = "select instance_id, %s 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");

Voici comment l'utiliser:

String sql = String.format(SQL, "SUBSTR(DSN,27,16)"); // This replaces the %s.
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1, defaultWasGroup);
preparedStatement.setString(2, "%Module=jvmRuntimeModule:freeMemory%");

Voir aussi :


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 ...





sql-like