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




utilisation de preparedstatement java (6)

Tu peux essayer:

String beforeAndAfter = "%" + yourVariable + "%";

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?


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 :


Cela devrait fonctionner:

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

Omettre le ' autour du ? . Sans le ' , ? est un espace réservé pour un paramètre. Avec elle, il s'agit d'une chaîne SQL (c'est-à-dire identique à "?" En Java).

Ensuite, vous devez concaténer la chaîne du côté Java; vous ne pouvez pas transmettre les fonctions SQL en tant que paramètres aux requêtes; Seules les valeurs de base (comme string, integer, etc.) car le pilote JDBC convertira le paramètre en type SQL, ce que la base de données attend, et il ne peut pas exécuter les fonctions SQL à cette étape.


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 :)


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






sql-like