it-swarm.com.de

Kann eine LIKE-Abfrage nicht in einem JDBC PreparedStatement verwenden?

Der Abfragecode und die Abfrage:

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

Gibt eine leere ResultSet zurück.

Durch einfaches Debuggen habe ich die dritte Bindung gefunden, die das Problem darstellt, d. H.

DSN like '?'

Ich habe alle möglichen Variationen ausprobiert, von denen die vernünftigste zu sein schien:

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

das funktioniert aber nicht, da mir ' auf beiden Seiten der verketteten Zeichenfolge fehlt, also versuche ich:

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

aber ich kann einfach keinen Weg finden, sie in diese Werke zu bringen.

Was vermisse ich?

28
SeerUK

Erstens sind die PreparedStatement-Platzhalter (diese ?-Dinge) nur für column-Werte, nicht für Tabellennamen, Spaltennamen, SQL-Funktionen Klauseln usw. Verwenden Sie stattdessen besser/- String#format() . Zweitens sollten Sie not die Platzhalter wie '?' angeben, es würde nur die letzte Abfrage falsch darstellen. Die PreparedStatement-Setter erledigen bereits das Zitieren (und das Umgehen) für Sie.

Hier ist die feste SQL:

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");

So verwenden Sie es:

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%");

Siehe auch:

56
BalusC

Es gibt zwei Probleme mit Ihrer Aussage. Sie müssen verstehen, wie Bindungsvariablen funktionieren. Die Abfrage wird nicht verarbeitet, indem Sie die Zeichen ? mit Ihren Parametern ersetzen. Stattdessen wird die Anweisung mit Platzhaltern kompiliert, und während der Ausführung werden die tatsächlichen Werte der Parameter an den DB übergeben.

Sie parsen also die folgende Abfrage:

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

Ich bin mir ziemlich sicher, dass der letzte Parameter ignoriert wird, da er sich in einer begrenzten Zeichenfolge befindet. Auch wenn es nicht ignoriert wird, ist es nicht sinnvoll, '-Zeichen zu haben, da Oracle einen Parameter nicht in eine Zeichenfolge einbinden kann (ich bin überrascht, dass es keinen Fehler ausgelöst hat.

Wenn Sie jetzt Ihren DNS LIKE '?' durch DSN LIKE ? ersetzen und "%Module=jvmRuntimeModule:freeMemory%" binden, ist dies sinnvoll und sollte die richtigen Zeilen zurückgeben.

Sie haben immer noch das Problem mit Ihrem ersten Parameter. Er wird nicht das tun, was Sie erwarten. I-e Die Abfrage, die ausgeführt wird, entspricht der folgenden Abfrage:

SELECT instance_id, 'SUBSTR(DSN,27,16)'
  FROM ...

das ist überhaupt nicht das Gleiche wie 

SELECT instance_id, SUBSTR(DSN,27,16)
  FROM ...

Ich würde vorschlagen, die folgende Abfrage zu parsen (= preparStatement), wenn Sie davon ausgehen, dass der SUBSTR dynamisch ist:

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
11
Vincent Malgrat

Wenn Sie LIKE in der vorbereiteten Anweisung verwenden möchten und auch% -Zeichen in LIKE verwenden möchten;

schreiben Sie die vorbereitete Anweisung wie gewohnt ".... LIKE? ...." und weisen Sie dem Fragezeichen den Parameterwert zu

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

Das wird funktionieren :)

11
csonuryilmaz

Lassen Sie den ' um den ? herum. Ohne ' ist ? ein Platzhalter für einen Parameter. Mit ihr ist es eine SQL-Zeichenfolge (d. H. Die gleiche wie "?" in Java).

Dann müssen Sie den String auf der Java-Seite verketten. Sie können SQL-Funktionen nicht als Parameter an Abfragen übergeben. Nur grundlegende Werte (wie Zeichenfolge, Ganzzahl usw.), da der JDBC-Treiber den Parameter in den SQL-Typ konvertiert, den die Datenbank erwartet, und in diesem Schritt keine SQL-Funktionen ausführen kann.

2
Aaron Digulla
PreparedStatement ps = con.prepareStatement(
    "select columname from tablename where LOWER(columnname) LIKE LOWER('"+var+"%')");  

Hier ist var die Variable, in der der Wert gespeichert wird, der gesucht werden soll ...

0
Saheba

Du kannst es versuchen:

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