19. januar 2003 - 01:01
Der er
40 kommentarer og 1 løsning
underlig SQL error
Hej jeg prøver på at få filnavne lagt ned i en access database. min kode ser således ud (har skåret lidt af :): File fil = new File(dir); File[] filerIDir = fil.listFiles(); // et array af filer i mappen "dir" oprettes for (int i = 0; i < filerIDir.length; i++) { if (filerIDir[i].isDirectory() == true) { dirSize(filerIDir[i].getAbsolutePath()); } else { String navn = filerIDir[i].getName(); String sti = filerIDir[i].getAbsolutePath(); System.out.println(navn); String query = "INSERT INTO filer(fil, sti) VALUES('"+navn+"','"+sti+"')"; try { insert.executeUpdate(query); } catch (SQLException e) { System.out.println("fejl ved indsættelse i filer " + e.getErrorCode() + ":" + e.getSQLState() + ":" + e.getMessage()); } } } funktionen hedder dirsize. mit problem er at jeg ved nogle filer får denne fejlmeddelse: fejl ved indsættelse i filer 0:null:Invalid handle det er feks filer med navne som: flashget_1.40.rar IsoBuster.v1.1.rar Total_Commander_5.5.rar jeg forstår ikke helt hva fejlen er for noget og hvorfor den kommer for den kommer ikke ved filer som: _ISDel.exe _Setup.dll _sys1.cab og de ligner jo (karaktermæsigt) de andre Håber i kan hjælpe :) ov forresten hvordan får man et filnavn der hedder kim's hat.jpg ned i db? Den lille ' giver nemlig fejl i SQL-strengen :/ Ska jeg lave en løkke der søger strengen igennem efter ' og erstatter dem med ´ eller er der en nemmere måde ? så har jeg ikke mere :) på forhånd tak NZC
Annonceindlæg tema
19. januar 2003 - 01:04
#1
Hvor lange er dine felter? Access har det med at brokke sig hvis du fx indsætter 30 tegn i et felt på 20 tegn Du kan erstatte alle forekomster af een ' med to, dvs: ''
19. januar 2003 - 01:05
#2
19. januar 2003 - 01:06
#3
jeg bruger memo eller notat som det hedder i access DK :) og den ka indeholde en masse så vidt jeg ved. du mener asso at en for-løkke der render filnavnet igennem er en ide ?
19. januar 2003 - 01:12
#4
Så skal jeg ikke kunne sige hvorfor - prøv evt et anden databasesystem ;) Du *bør* bruge PreparedStatement
19. januar 2003 - 10:59
#5
Prøv lige med: try { System.out.println(query); insert.executeUpdate(query); } catch (SQLException e) { e.printStackTrace(); } og lad os se output.
19. januar 2003 - 11:01
#6
Og Erik har ret m.h.t. at preparedStatement løser problemet med strenge med quotes i.
19. januar 2003 - 12:47
#7
her er resultatet af system.out.print INSERT INTO filer(fil) VALUES('Powerquest.Partition.Magic.EN.v8.0.1242.zip') fejl ved indsættelse i filer 0:null:Invalid handle der er blot en af dem der gir fejl. jeg prøver lige det med prepared statements :)
19. januar 2003 - 12:53
#8
er det så sådan her man bruger prepared statements PreparedStatement pstmt = con.prepareStatement("INSERT INTO filer(fil) VALUES('?')"); eller? Jeg bruger jo Strings og pstmt.setString() tager en int og en String ind. Hva er int'en for noget ?
19. januar 2003 - 12:53
#9
Med fare for at lyde dum :) - men er du sikker på det er et notat-felt og ikke et text-felt på 20 tegn ?
19. januar 2003 - 12:54
#10
PreparedStatement pstmt = con.prepareStatement("INSERT INTO filer(fil) VALUES(?)"); og så setString med dit filnavn
19. januar 2003 - 12:55
#11
Nå ja, tallet (int-en) er nummeret på spørgsmålstegnet. Du skal skrive 1 - der er jo kun det samme
19. januar 2003 - 13:02
#12
jeg har lige ændret felterne i db til tekststrenge på 255 :) så nu er jeg sikker på at de er store nok :) når jeg vil execute mit pstmt er det så pstmt.executeUpdate(); ?
19. januar 2003 - 13:15
#13
Ja - det er excecuteUpdate uden argument, fordi du angiver SQL i prepareStement og værdi i setString.
19. januar 2003 - 13:15
#14
Og jeg kunne staadigvæk godt tænke mig at se den fulde printStackTrace.
19. januar 2003 - 13:18
#15
Umiddelbart lyder fjelen nemlig ikek som det har noget med hverken værdi eller feltets datatype at gøre. Men snarere som om forbindelsen til databasen er væk.
19. januar 2003 - 13:25
#16
nu har jeg jo ændret en masse i programmet og nu virker det slet ikke :( men printstacktrace giver java.sql.SQLException: General error at sun.jdbc.odbc.JdbcOdbc.throwGenericSQLException(JdbcOdbc.java:7008) at sun.jdbc.odbc.JdbcOdbc.SQLAllocStmt(JdbcOdbc.java:174) at sun.jdbc.odbc.JdbcOdbcConnection.prepareStatement(JdbcOdbcConnection.java:465) at sun.jdbc.odbc.JdbcOdbcConnection.prepareStatement(JdbcOdbcConnection.java:443) nu vil den slet ikke indsætte noget som helst i db
19. januar 2003 - 13:29
#17
Din kode?
19. januar 2003 - 13:30
#18
File fil = new File(dir); PreparedStatement pstmt = con.prepareStatement("INSERT INTO filer(fil) VALUES('?')"); File[] filerIDir = fil.listFiles(); for (int i = 0; i < filerIDir.length; i++) { if (filerIDir[i].isDirectory() == true) { dirSize(filerIDir[i].getAbsolutePath()); } else { String navn = filerIDir[i].getName(); String sti = filerIDir[i].getAbsolutePath(); System.out.println(navn); try { pstmt.setString(1, navn); pstmt.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } } } ?
19. januar 2003 - 13:33
#19
import java.io.File; import java.awt.*; import java.sql.*; public class filtest { private static Connection con; private static PreparedStatement pstmt; public static void dirSize(String dir) { try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); } catch (Exception e) { System.out.println("Failed to load JDBC/ODBC driver."); } try { con = DriverManager.getConnection("jdbc:odbc:filer", "", ""); } catch (Exception e) { e.printStackTrace(); } long res = 0; File fil = new File(dir); File[] filerIDir = fil.listFiles(); // et array af filer i mappen "dir" oprettes for (int i = 0; i < filerIDir.length; i++) { if (filerIDir[i].isDirectory() == true) { dirSize(filerIDir[i].getAbsolutePath()); } else { String navn = filerIDir[i].getName(); try { pstmt = con.prepareStatement("INSERT INTO filer(fil) VALUES(?)"); pstmt.setString(1, navn); pstmt.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } } } /* Lav en løkke der løber igennem filerIDir, og undersøger hver eneste fil. Hvis det er en mappe skal metoden kalde sig selv og tælle res op med en hel mappes indhold, hvis det er en "normal" fil skal res blot tælles op. */ try { pstmt.close(); con.close(); } catch (SQLException se) { System.out.println(se); } }
19. januar 2003 - 13:35
#20
Det er ikke skyld i fejlen, men pstmt = con.prepareStatement("INSERT INTO filer(fil) VALUES(?)"); bør flyttes udenfor for-løkken.
19. januar 2003 - 13:38
#21
JDBC ODBC bridgen kan iøvrigt godt drille lidt. Så prøv evt. en klassisk løsning: luk ned, reboot PC og prøv igen.
19. januar 2003 - 13:56
#22
hmmm har lige rebootet pstmt.setString(1, navn); <--- den udløser den her java.sql.SQLException: Invalid handle at sun.jdbc.odbc.JdbcOdbc.standardError(JdbcOdbc.java:7051) at sun.jdbc.odbc.JdbcOdbc.SQLBindInParameterString(JdbcOdbc.java:980) at sun.jdbc.odbc.JdbcOdbcPreparedStatement.setChar(JdbcOdbcPreparedStatement.java:3106) at sun.jdbc.odbc.JdbcOdbcPreparedStatement.setString(JdbcOdbcPreparedStatement.java:764) hjælp ?!
19. januar 2003 - 14:05
#23
Det er heller ikke særlig smart at åbne en forbindelse for hvert rekursivt kald. Det bør du kun gøre én gang.
19. januar 2003 - 14:06
#24
ye det ved jeg godt :) men det er blot en lille test
19. januar 2003 - 14:13
#25
Erik du har fundet problemet ! con er static !! Så når man kalder rekursivt laver man en ny con som bliver closet og så returnerer man tilbage og bruger con igen !!!
19. januar 2003 - 14:15
#26
import java.io.File; import java.awt.*; import java.sql.*; public class filtest { private static Connection con = null; private static PreparedStatement pstmt; public static void dirSize(String dir) { if(conn == null) { try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); } catch (Exception e) { System.out.println("Failed to load JDBC/ODBC driver."); } try { con = DriverManager.getConnection("jdbc:odbc:filer", "", ""); pstmt = con.prepareStatement("INSERT INTO filer(fil) VALUES(?)"); } catch (Exception e) { e.printStackTrace(); } } long res = 0; File fil = new File(dir); File[] filerIDir = fil.listFiles(); // et array af filer i mappen "dir" oprettes for (int i = 0; i < filerIDir.length; i++) { if (filerIDir[i].isDirectory() == true) { dirSize(filerIDir[i].getAbsolutePath()); } else { String navn = filerIDir[i].getName(); try { pstmt.setString(1, navn); pstmt.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } } } }
19. januar 2003 - 14:18
#27
Jeg har lige omformateret koden lidt: import java.io.File; import java.awt.*; import java.sql.*; public class FilTest { private static Connection con = null; private static PreparedStatement pstmt; public static void dirSize(String dir) { if (con == null) { try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); } catch (Exception e) { System.out.println("Failed to load JDBC/ODBC driver."); } try { con = DriverManager.getConnection("jdbc:odbc:filer", "", ""); pstmt = con.prepareStatement("INSERT INTO filer(fil) VALUES(?)"); } catch (Exception e) { e.printStackTrace(); } } long res = 0; File fil = new File(dir); File[] filerIDir = fil.listFiles(); for (int i = 0; i < filerIDir.length; i++) { if (filerIDir[i].isDirectory() == true) { dirSize(filerIDir[i].getAbsolutePath()); } else { String navn = filerIDir[i].getName(); try { pstmt.setString(1, navn); pstmt.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } } } } }
19. januar 2003 - 14:21
#28
aaaaaahhhhh mange tak for tålmodigheden :) hvis nu jeg vil bruge en mysql db i stedet, kender i så et godt stedd til en lille tutorial eller ka i lige slynge en løsning ud ? Jeg har oprettet mysql-db'en men mangler forbindelse til den Mange tak NZC
19. januar 2003 - 14:23
#29
Du skal kun rette 2 linier for at skifte fra Access til MySQL: Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); skal rettes til for at bruge MySQL JDBC driver. con = DriverManager.getConnection("jdbc:odbc:filer", "", ""); skal rettss til for at bruge MySQL URL.
19. januar 2003 - 14:29
#31
tester det lige :) Mange tak
19. januar 2003 - 14:32
#32
Vær lige opmærksom på, at MySQL JDBC driver skal downloades separat (kommer ikek sammen med selve MySQL). Og i modsætning til JDBC ODBC bridge der altid er i classpath, så skal MySQL JDBC JAR filen eksplicit anbrindes i classpath.
19. januar 2003 - 14:44
#33
jeg ska oprette min db i data source og mysql-driveren kræver windows DNS. jeg er den største n00b hva netværk og DNS angår :) hva er det lige windows DNS er og hvor ka jeg se det henne ?
19. januar 2003 - 14:45
#34
hehe havde ikke refreshet :)
19. januar 2003 - 14:46
#35
Lad være med at bruge MySQL ODBC driver og JDBC ODBC bridge. Download mySQL JDBC driver, udpak den og brug den.
19. januar 2003 - 14:49
#36
den bruger jeg sådan her ?
MySQL driver er:
com.mysql.jdbc.Driver
MySQL URL syntax er:
jdbc:
mysql://hostnavn/databasenavn ?
19. januar 2003 - 14:53
#37
Class.forName("com.mysql.jdbc.Driver");
...
con = DriverManager.getConnection("jdbc:
mysql://hostnavn/databasenavn" , "", "");
19. januar 2003 - 15:01
#38
hmm
den her con = DriverManager.getConnection("jdbc:
mysql://localhost/filer" , "root", "");
er skyld i den her
java.sql.SQLException: No suitable driver
at java.sql.DriverManager.getConnection(DriverManager.java:532)
at java.sql.DriverManager.getConnection(DriverManager.java:171)
jeg har pakket .jar-filen ud og lagt mm.mysql-2.0.14-bin.jar i min class-path som README'en siger
19. januar 2003 - 15:05
#39
Ah. Der er 2 forskellige JDBC drivere til MySQL. Jeg bruger den der er i mysql-connector-java-2.0.14-bin.jar ! Driveren hedder noget andet i den du har.
19. januar 2003 - 15:06
#40
Brug: org.gjt.mm.mysql.Driver
19. januar 2003 - 16:00
#41
sådan så virker det med mysql :) mange tak arne_v :)))) NZC
Kurser inden for grundlæggende programmering