Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
Ich komme bei einem simplen Statement in Derby nicht weiter. Es gibt einen Tag auf der Tabelle TAGS der sich test nennt. Wenn ich mit Equal danach suche ist es kein Problem, Like ohne Wildcards funktioniert auch, sobald ich aber die Wildcards % oder _ benutze findet er den Eintrag nicht mehr. z.B.
SELECT ID,TAG FROM TAGS where (TAG = 'test') //Funktioniert
SELECT ID,TAG FROM TAGS where (TAG LIKE 'tes%') // Funktioniert nicht
SELECT ID,TAG FROM TAGS where (TAG LIKE 'tes_')// Funktioniert nicht
SELECT ID,TAG FROM TAGS where (TAG LIKE 'test%') //Funktioniert
SELECT ID,TAG FROM TAGS where (TAG LIKE 'test_')// Funktioniert nicht
Habe das ganze nochmal ausprobiert und unter anderem den SQL Befehl rein als String fest reingeschrieben und es hat funktioniert.
Was ich mache ist, ich bekomme per request.getParameter("Search") einen String. Dieser wird in tokens aufgeteilt, anschliessend ersetze ich die Zeichen * und ? mit den für die Datenbank verständlichen % und _. Dann setze ich den String für die abfrage zusammen.
Ich kann mir irgendwie nicht erklären woran es liegen könnte, das Encoding der Page ist UTF-8 und wie vorhin gepostet wird die SQL Abfrage richtig zusammengesetzt.
Zeig doch mal den Code, oder am Besten ein KSKB wo du den Suchstring fest reinschreibst. Ansonsten lass dir die Query doch mal ausgeben was du da zusammenbaust. Ansonsten sei dir noch empfohlen PreparedStatements zu benutzen.
Naja ich glaub net das PreparedStatements so wandelbar sind das die hier genügen würden. Der Code ist hier, evt. noch bissl schwer verständlich änder ich noch wenn er mindestens mal läuft.
Den Suchstring geb ich mit aus und der sieht genau so aus wie ich Ihn beim ersten post reingestellt habe.
Java:
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
ArrayList<String[]> required = new ArrayList<String[]>();
ArrayList<String[]> optional = new ArrayList<String[]>();
ArrayList<String[]> notIncluded = new ArrayList<String[]>();
ArrayList<String> requiredManual = new ArrayList<String>();
Connection conn = Def.getConn();
Statement st = null;
ResultSet rs = null;
PrintWriter out = response.getWriter();
out.println(WebTemplates.getHeader());
String searchString = null;
if ((searchString = request.getParameter("SEARCH").trim()).length() > 0) {
StringTokenizer token = new StringTokenizer(searchString);
while (token.hasMoreTokens()) {
String tmp = token.nextToken();
String[] arr = null;
if (tmp.contains("*") || tmp.contains("?")) {
requiredManual.add(tmp.replaceAll("-", "").replaceAll("\\+", ""));
tmp = tmp.replaceAll("\\*", "%");
tmp = tmp.replaceAll("\\?", "_");
arr = new String[]{tmp, "1"};
} else {
arr = new String[]{tmp, "0"};
}
if (arr[0].charAt(1) == '-') {
arr[0] = arr[0].substring(1);
notIncluded.add(arr);
} else if (tmp.charAt(1) == '+') {
arr[0] = arr[0].substring(1);
required.add(arr);
} else {
optional.add(arr);
}
}
StringBuilder sbInc = new StringBuilder();
StringBuilder sb = new StringBuilder();
Iterator<String[]> sbIt1 = optional.iterator();
Iterator<String[]> sbIt2 = required.iterator();
Iterator<String[]> sbIncIt1 = notIncluded.iterator();
while (sbIt2.hasNext()) {
String[] tmp = sbIt2.next();
if (sbIt2.hasNext()) {
if (tmp[1].equals("0")) {
sbInc.append("TAG = '").append(tmp[0]).append("' or ");
} else {
sbInc.append("TAG LIKE '").append(tmp[0]).append("' or ");
}
} else {
if (tmp[1].equals("0")) {
sbInc.append("TAG = '").append(tmp[0]);
} else {
sbInc.append("TAG LIKE '").append(tmp[0]);
}
}
}
while (sbIt1.hasNext()) {
String[] tmp = sbIt1.next();
if (sbIt1.hasNext()) {
if (tmp[1].equals("0")) {
sbInc.append("TAG = '").append(tmp[0]).append("' or ");
} else {
sbInc.append("TAG LIKE '").append(tmp[0]).append("' or ");
}
} else {
if (tmp[1].equals("0")) {
sbInc.append("TAG = '").append(tmp[0]).append("'");
} else {
sbInc.append("TAG LIKE '").append(tmp[0]).append("'");
}
}
}
while (sbIncIt1.hasNext()) {
String[] tmp = sbIncIt1.next();
if (sbIncIt1.hasNext()) {
if (tmp[1].equals("0")) {
sb.append("TAG = '").append(tmp[0]).append("' or ");
} else {
sb.append("TAG LIKE '").append(tmp[0]).append("' or ");
}
} else {
if (tmp[1].equals("0")) {
sb.append("TAG = '").append(tmp[0]).append("'");
} else {
sb.append("TAG LIKE '").append(tmp[0]).append("'");
}
}
}
try {
st = conn.createStatement();
String notIncl = " and not(" + sb.toString() + ")";
System.out.println("SELECT ID,TAG FROM TAGS where (" + sbInc.toString() + ")"+(sb.length()>0?notIncl:""));
rs = st.executeQuery("SELECT ID,TAG FROM TAGS where (" + sbInc.toString() + ")"+(sb.length()>0?notIncl:""));
Set<Long> hm = new HashSet<Long>();
boolean reqInc = false;
while (rs.next()) {
if (requiredManual.isEmpty()) {
hm.add(rs.getLong("ID"));
} else {
String tag = rs.getString("TAG");
Iterator<String> tagIt = requiredManual.iterator();
while (tagIt.hasNext()) {
if (tag.matches("^" + tagIt.next() + "$")) {
hm.add(rs.getLong("ID"));
}
}
}
}
if (hm.isEmpty()) {
out.println("Es wurden keine Übereinstimmungen gefunden!");
} else {
Iterator<Long> it = hm.iterator();
while (it.hasNext()) {
Long ID = it.next();
rs = st.executeQuery("Select KDBENTRYS.ID,KDBENTRYS.TITLE,Tags.TAG FROM KDBENTRYS JOIN TAGS ON (KDBENTRYS.ID = TAGS.ID) where KDBENTRYS.ID = " + ID.toString());
boolean proof = true;
while (rs.next()) {
if (proof) {
out.println("<A HREF=\"\">" + rs.getString("ID") + "</a> " + rs.getString("TITLE") + "</BR>");
out.println("<A HREF=\"\">" + rs.getString("TAG"));
proof = false;
} else {
out.println(",<A HREF=\"\">" + rs.getString("TAG"));
}
//out.println("<hr style=\"width:300px; color:yellow; background-color:yellow; height:5px;margin-right:0; text-align:right; border:1px dashed blue;\">");
}
}
}
} catch (SQLException ex) {
Logger.getLogger(SimpleServlet.class.getName()).log(Level.SEVERE, null, ex);
}
} else {
out.println("Es wurden keine Suchparameter mitgegeben!");
}
out.println(WebTemplates.getFooter());
out.close();
}
Das einzige was da noch fehlt ist Tomatensauce und Parmesan...
Sorry, aber wie su siehst funktioniert dein Code nicht, die SQL Statements die du oben gepostet hast funktionieren 100%, offensichtlich (und nachvollziehbar) hast du den Überblick verloren, ein KSKB ist auch etwas anderes.
Würde an deiner Stelle den Spaghetticode aufräumen, mache dir zusätzliche Methoden & Klassen, beides immer so kurz wie möglich, und Methoden dann noch kürzer. Teile und herrsche, ansonsten wirst du beherrscht!
Ist wie immer nicht böse gemeint, musste aber gesagt werden, da drinnen brauchst du nicht nach erst Bugs suchen, ist Zeitverschwendung.
Wie erwähnt, ich weiss der Code ist unübersichtlich.
Der Witz is die SQL Statements die ich anfangs gepostet habe sind direkt aus dem Output oberhalb des SQL execute und sobald ich die ausschreibe also nicht "zusammensetze" funtkioniert das und mir geht nicht in den Kopf warum das nicht funktionieren sollte.
Ich versuch ma den Code bissl in den Griff zu bekommen und poste ihn oben nochmal. Über Ideen wäre ich trotzdem Froh den ich kanns mir einfach nicht erklären warum das nicht tun sollte.
Du machst dir selber das Leben leichter wenn du nicht Code wie oben produzierst, falls jemand nach dir deinen Code warten muss, kannst du nur hoffen dass er nicht weiss wo du wohnst.
Vielleciht hast du auch einfach die falsche Art von Apostrophen verwendet, [c]'[/c] vs. [c]`[/c] vs [c]'[/c]. '`'
Jo das witzige ist nur dass das Statement ja augenscheindlich korrekt ist...
Habe jetzt aber nochmal Ordnung in den Code gebracht und das hat geholfen... ich weiss aber immernoch nicht wieso.....
Hier der neue Code:
Java:
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println(WebTemplates.getHeader());
String searchString = request.getParameter("SEARCH");
if (searchString.length() == 0) {
out.println("Es wurden keine Suchparameter mitgegeben!");
out.println(WebTemplates.getFooter());
out.close();
return;
}
createArrays(searchString);
Set<Long> searchResult = null;
try {
searchResult = createAndExecuteStatement();
} catch (SQLException ex) {
Logger.getLogger(SimpleServlet.class.getName()).log(Level.SEVERE, null, ex);
}
if (searchResult.isEmpty()) {
out.println("Es wurden keine Übereinstimmungen gefunden!");
out.println(WebTemplates.getFooter());
out.close();
return;
}
writeResults(out, searchResult);
out.println(WebTemplates.getFooter());
out.close();
}
private void createArrays(String search) {
StringTokenizer token = new StringTokenizer(search);
while (token.hasMoreTokens()) {
String tmp = token.nextToken();
String[] arr = null;
if (tmp.contains("*") || tmp.contains("?")) {
required.add(tmp.replaceAll("-", "").replaceAll("\\+", ""));
tmp = tmp.replaceAll("\\*", "%");
tmp = tmp.replaceAll("\\?", "_");
arr = new String[]{tmp, "LIKE"};
} else {
arr = new String[]{tmp, "="};
}
if (arr[0].charAt(1) == '-') {
arr[0] = arr[0].substring(1);
excluded.add(arr);
} else if (tmp.charAt(1) == '+') {
arr[0] = arr[0].substring(1);
included.add(arr);
} else {
included.add(arr);
}
}
}
private void writeResults(PrintWriter out, Set<Long> results) {
Connection conn = Def.getConn();
Statement st = null;
ResultSet rs = null;
try {
st = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
Iterator<Long> it = results.iterator();
while (it.hasNext()) {
Long ID = it.next();
rs = st.executeQuery("Select KDBENTRYS.ID,KDBENTRYS.TITLE,Tags.TAG FROM KDBENTRYS JOIN TAGS ON (KDBENTRYS.ID = TAGS.ID) where KDBENTRYS.ID = " + ID.toString());
while (rs.next()) {
if (rs.isFirst()) {
out.println("<A HREF=\"\">" + rs.getString("ID") + "</a> " + rs.getString("TITLE") + "</BR>");
}
out.println("<A HREF=\"\">" + rs.getString("TAG"));
}
}
} catch (SQLException ex) {
Logger.getLogger(SimpleServlet.class.getName()).log(Level.SEVERE, null, ex);
}
}
private StringBuilder createSQLValidate(ArrayList<String[]> input, StringBuilder SQLString) {
int lastEntry = input.size() - 1;
for (int i = 0; i < input.size(); i++) {
String[] tmp = input.get(i);
SQLString.append("TAG ");
SQLString.append(tmp[1]);
SQLString.append(" '");
SQLString.append(tmp[0]);
SQLString.append("'");
if (i < lastEntry) {
SQLString.append(" or ");
}
}
input.clear();
return SQLString;
}
private Set<Long> createAndExecuteStatement() throws SQLException {
Connection conn = Def.getConn();
Statement st = null;
ResultSet rs = null;
Set<Long> searchResult = new HashSet<Long>();
StringBuilder include = new StringBuilder();
StringBuilder exclude = new StringBuilder();
exclude.append(" and not(");
exclude = createSQLValidate(excluded, exclude);
exclude.append(")");
include = createSQLValidate(included, include);
st = conn.createStatement();
System.out.println("SELECT ID,TAG FROM TAGS WHERE (" + include.toString() + ")" + (exclude.length() > 10 ? exclude : ""));
rs = st.executeQuery("SELECT ID,TAG FROM TAGS WHERE (" + include.toString() + ")" + (exclude.length() > 10 ? exclude : ""));
while (rs.next()) {
if (required.isEmpty()) {
searchResult.add(rs.getLong("ID"));
} else {
String tag = rs.getString("TAG");
Iterator<String> tagIt = required.iterator();
while (tagIt.hasNext()) {
if (tag.matches("^" + tagIt.next() + "$")) {
searchResult.add(rs.getLong("ID"));
}
}
}
}
return searchResult;
}
Darf den sowas als geordneter Code bezeichnet werden? oder müsst ich das noch auf klassen aufsplitten?
EDIT: Das ganze verhält sich wie eine Wundertüte.... ich geb einen String mit, es tut nicht, anderer String klappt dann und wenn ich dann den vorherigen nochmal ausführe klappt der auch
SELECT ID,TAG FROM TAGS WHERE (TAG = 'test')
Results Found: 1
SELECT ID,TAG FROM TAGS WHERE (TAG LIKE 'tes%')
Results Found: 0
SELECT ID,TAG FROM TAGS WHERE (TAG LIKE 'test%')
Results Found: 1
SELECT ID,TAG FROM TAGS WHERE (TAG LIKE 'tes%')
Results Found: 1
SELECT ID,TAG FROM TAGS WHERE (TAG LIKE 'tes_')
Results Found: 1
SELECT ID,TAG FROM TAGS WHERE (TAG LIKE 'te%')
Results Found: 1
SELECT ID,TAG FROM TAGS WHERE (TAG LIKE 'te%') and not(TAG = 'hard')
Results Found: 1
SELECT ID,TAG FROM TAGS WHERE (TAG LIKE 'te%') and not(TAG = 'hardcore')
Results Found: 1
SELECT ID,TAG FROM TAGS WHERE (TAG LIKE 'te%') and not(TAG LIKE '_lubb')
Results Found: 1
Dazu ist gesagt das auf der DB ein Eintrag erfasst ist mit den Tags (test,blubb,hardcore)
Mehr Methoden (vor allem viel kürzere) und mehr Klassen.
Vor allem solltest du besser trennen.
Im Moment hast du ein Servlet, in dem mehrere Sprachen (4!!!) gemischt werden (Java, HTML, SQL, RegEx, später wohl noch JavaScript und CSS).
Solltest zumindest das SQL komplett in eine andere Klasse verschieben, suche mal nach dem DAO Pattern.
Dann sollltest du die Konzepte und Aufgaben sauberer trennen, suche mal "Single Responsibility Principle" und "Seperation of Concerns".
Die Ergebnisse sollten von einer JSP oder einem anderen View templating angezeigt werden, nciht im Servlet direkt, MVC bzw. "Model 2" währen die Suchbegriffe.
Ja, das ist viel für den Anfang.
Um nicht immer nur zu nörgeln: Du hast schon einen Schritt in die richtige Richtung gemacht.
Zu deinem konkreten Problem:
Solltest deine DB in den Griff bekommen, irgendwie läuft das etwas sehr schräg...
Dafür solltest du erstmal alles so einfach wie möglich halten, zB. eine "Testklasse" in der du nur SQL Statements an die DB schickst, kein HTML, RegEX, etc. pp.
Wie bekommst du denn die Testdaten in die DB?
Also an der Datenbank liegts nicht. Jede Query liefert immer das selbe Ergebnis (solange man die Daten nicht ändert).
D.h. du hast irgendwo einen Bug im Code.