SQL-Statement SQLException: '' is not a valid name.

nahum77

Mitglied
Hallo zusammen

Ich bin mit meinem Latein wirklich am Ende und brauch hier mal Unterstützung!

Worum gehts:
Ich versuch durch Java mit SQL-Preparestatement in eine Access (2003) Tabelle zu schreiben. Die Acces Tabelle wiederum ist mit einem MS Sharepoint (2003) verlinkt.

Hier das Preparestatement:
SQL:
UPDATE [ChangeCalendar: v_stefan]  SET `Change ID` = ?,`Departement` = ?,`Anfangszeit` = ?,`Endzeit` = ? WHERE `Change ID` = ? AND Departement = ?

Die Parameter für den ersten Datensatz werden wie folgt gesetzt:

Change ID: CRQ000000040605
Departement: I
Anfangszeit: 2025-05-31 00:00:00
Endzeit: 2025-07-24 00:00:00
Change ID: CRQ000000040605
Departement: I
Wenn ich das Statement ausführe (Connection steht und preparestatement wurde gesetzt)
Java:
int updateCount = mPSU.executeUpdate();
erhalte ich folgende Exception:
Java:
java.sql.SQLException: [Microsoft][ODBC Microsoft Access Driver] '' is not a valid name.  Make sure that it does not include invalid characters or pun
ctuation and that it is not too long.
        at sun.jdbc.odbc.JdbcOdbc.createSQLException(Unknown Source)
        at sun.jdbc.odbc.JdbcOdbc.standardError(Unknown Source)
        at sun.jdbc.odbc.JdbcOdbc.SQLExecute(Unknown Source)
        at sun.jdbc.odbc.JdbcOdbcPreparedStatement.execute(Unknown Source)
        at sun.jdbc.odbc.JdbcOdbcPreparedStatement.executeUpdate(Unknown Source)
        at synchronizer2.Sync.clearSPFlag(Sync.java:507)
        at synchronizer2.Sync.update(Sync.java:642)
        at synchronizer2.Sync.sync_change(Sync.java:209)
        at synchronizer2.Sync.<init>(Sync.java:130)
        at synchronizer2.MyTimer.work(MyTimer.java:114)
        at synchronizer2.MyTimer.access$000(MyTimer.java:24)
        at synchronizer2.MyTimer$1.run(MyTimer.java:65)
        at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
        at java.util.concurrent.FutureTask$Sync.innerRunAndReset(Unknown Source)
        at java.util.concurrent.FutureTask.runAndReset(Unknown Source)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(Unknown Source)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(Unknown Source)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)

Ich habe schon beinahe jegliche Kombination und Möglichkeit probiert. Bei den Begrenzern mit ' oder ` oder " ist immer dasselbe oder der Treiber reklamiret wegen Syntaxe oder too few Paramter oder so. Auch den Tabellennamen mit " zu begrenzen hat nichts gebracht.

Bei den Dates für Anfangs- und Endzeit habe ich zunächst versucht mit Timestamp zu arbeiten aber Access (oder wahrscheinlich eher der Sharepoint) hat ein Prob mit den Millisekunden. Daher übergebe ich das Datum nun als String (bei INSERT hat das so funktioniert).

Bei Dr. Google liest mann dazu öfters was von Apostrophs oder anderen Sonderzeichen in Pfaden. Ich verwende aber keine Pfade oder ist der Pfad im ODBC zur DB gemeint oder allenfalls der Link der DB zum Sharepoint? Ich blick nicht mehr durch! ???:L

Aus dem ODBC-trace bin ich auch nicht schlau geworden. Jrgend wo steht dann:
Synchronizer2 142c-15b8 EXIT SQLExecute with return code -1 (SQL_ERROR)
HSTMT 031F3AA8

oder etwas weiter:
Synchronizer2 142c-15b8 EXIT SQLErrorW with return code 100 (SQL_NO_DATA_FOUND)
HENV 00000000
HDBC 00000000
HSTMT 031F3AA8
WCHAR * 0x031BF584 (NYI)
SDWORD * 0x031BF5CC
WCHAR * 0x031BF184
SWORD 300
SWORD * 0x031BF5C8
In der Tablle ist der Datensatz vorhanden und die Parameter stimmen auch überein.

Als Anhang noch der ODBC-Trace. Die Stellen wo es interessant zu werden scheint findet man am bestem mit suchen nach

Hoffe wirklich sehr, dass mir hier jemand helfen kann.
Herzlichen Dank schon mal im Voraus.

Grüsse
Nahum77
 

Anhänge

  • SQL-LOG.zip
    5,1 KB · Aufrufe: 2

nahum77

Mitglied
Herzlichen Dank für die schnelle Antwort.

Habe gleich dazu noch Fragen:

Access kann leider kein Prepare. Deshalb wird das so nicht funktionieren.

Das ist sicher so, aber ich hoffe bald auf einen MS SQL Server wechseln zu können und habe daher schon etwas voraus gedacht (oder versucht...)

Allerdings sollte das mit den Prepare auf Access laut API auch gehn da der Treiber damit umgehen können sollte:
Note: This method is optimized for handling parametric SQL statements that benefit from precompilation. If the driver supports precompilation, the method prepareStatement will send the statement to the database for precompilation. Some drivers may not support precompilation. In this case, the statement may not be sent to the database until the PreparedStatement object is executed. This has no direct effect on users; however, it does affect which methods throw certain SQLException objects.

Bei einem INSERT hab ich das schon mal gemacht und da hat es geklappt (hat wahrscheinlich wirklich der Treiber für mich umgemüntzt).

Diese Zeichen solltest Du überhaupt weglassen, denn damit kann m.E. nur MySQL etwas anfangen und selbst da ist es läßtig.

Wie kann ich dann Spaltennamen mit Leerschlägen begrenzen? Ist natürlich auch unschön Spaltennamen mit Spaces zu führen, in dem Fall ist das aber ein Zugeständniss an den Sharepoint der den Spaltennamen 1:1 übernimmt und so darstellt. Ausserdem ist der Sharepoint nicht in meiner Verantwortung und ich kann da kaum Einfluss nehmen.

Nochmals Danke und Gruss
Nahum77
 

bronks

Top Contributor
Freut mich, daß ich etwas beitragen konnte. :)

... Allerdings sollte das mit den Prepare auf Access laut API auch gehn da der Treiber damit umgehen können sollte: ... Bei einem INSERT hab ich das schon mal gemacht und da hat es geklappt (hat wahrscheinlich wirklich der Treiber für mich umgemüntzt).
Das ist eine Überraschung. Hättest Du bitte einen Link zu der Stelle in der API für mich.


... Wie kann ich dann Spaltennamen mit Leerschlägen begrenzen? ...
Den Spaltennamen mußt Du dafür in eckige Klammern setzten.
 

nahum77

Mitglied
Hallo nochmals

Habe was gefunden bin mir aber nicht sicher ob ich auf dem richtigen Weg bin.
Irgendwo hat einer geschrieben, dass der Sharepoint nur updates akzeptiert die auf die ID (Autowert) der verlinkten Tabelle referenzieren.

Also mach ich nun erst ein SELECT auf die ID und gebe diese in der UPDATE WHERE Clausel mit:

Das Select Statement:
SQL:
SELECT [ID] FROM [ChangeCalendar: v_stefan] WHERE [Change ID] = ? AND Departement = ?

Die ID erhalte ich zurück und nun das Update Statement:
SQL:
UPDATE [ChangeCalendar: v_stefan]  SET [Change ID] = ?,[Departement] = ?,[Anfangszeit] = ?,[Endzeit] = ? WHERE [ID] = ?

Und tatsächlich tut sich was, das heisst zumindest ist die SQL Exception eine andere ;:)
Java:
java.sql.SQLException: [Microsoft][ODBC Microsoft Access Driver] Operation must use an updateable query.
        at sun.jdbc.odbc.JdbcOdbc.createSQLException(Unknown Source)
        at sun.jdbc.odbc.JdbcOdbc.standardError(Unknown Source)
        at sun.jdbc.odbc.JdbcOdbc.SQLExecute(Unknown Source)
        at sun.jdbc.odbc.JdbcOdbcPreparedStatement.execute(Unknown Source)
        at synchronizer2.Sync.update(Sync.java:666)
        at synchronizer2.Sync.sync_change(Sync.java:209)
        at synchronizer2.Sync.<init>(Sync.java:130)
        at synchronizer2.MyTimer.work(MyTimer.java:114)
        at synchronizer2.MyTimer.access$000(MyTimer.java:24)
        at synchronizer2.MyTimer$1.run(MyTimer.java:65)
        at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
        at java.util.concurrent.FutureTask$Sync.innerRunAndReset(Unknown Source)
        at java.util.concurrent.FutureTask.runAndReset(Unknown Source)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(Unknown Source)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(Unknown Source)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)

Hierzu gibt es nun reichlich Posts im Netz wobei die meisten auf ein Berechtigungsproblem zielen. Das wiederum kann ich nicht nachvollziehn, denn bevor ich update, lösche ich gewisse Datensätze und das geht tiptop. Allerdings benuze ich dafür kein PreparedStatement sondern:
SQL:
DELETE FROM [ChangeCalendar: v_stefan] WHERE (Anfangszeit < (now-30))

Könnte also sein, dass bronks doch recht hat und PreparedStatements mit Access nicht gehn. Warum das dann mit dem INSERT und PreparedStatement funktioniert hat.....:bahnhof:

Ich mach nun mal ein par Tests, mal schauen was dabei raus kommt.

Wenn noch jemand eine Rat weiss wäre ich sehr dankbar. Langsam weiss ich wirklich nicht mehr was ich noch probieren könnte.

Grüsse
nahum77
 

bronks

Top Contributor
Du könntest noch eine Sache probieren: Laß testhalber die Anfangszeit und die Endzeit in Deinem Statement weg. Ich meine, daß es da zusätzlich ein Problem beim Parametrieren mit setDate() gibt, da es auf dem SQL Server auch schon mal Probleme damit gab.

Hier der Link:
Connection (Java 2 Platform SE 5.0)
Achso, ja! Ich dachte, daß Du ein Dokument zu Access gemeint hast.
 

nahum77

Mitglied
Hallo zusammen

So ich denke ich habe das Rätsel gelöst!

Zuerst aber mal meine Erkenntnisse aus den Test:

1. PreparedStatement über JDBC:ODBC auf Ms Access funktionieren einwandfrei und ohne Einschränkung. Folgender Test schreib, liest, updatet, liest wieder und löscht schliesslich den Datensatzläuft und das ohne Probleme.

Java:
  private void test1() throws SQLException, InterruptedException {

    String changeID = "MyTest";
    String departement = "T";
    String anfangszeit = "2041-09-01 17:00:00";
    String endzeit = "2041-09-01 18:00:00";
    String freigabe = "Test";
    long id = -1L;

    System.out.println("Values:" + changeID + "; " + departement + "; " + anfangszeit + "; " + endzeit);

    String sql_insert = "INSERT INTO [" + mTablesAndColumns[1] + "] " + getInsert() + " VALUES " + getQM();
    System.out.println("SQL-Statement: " + sql_insert);
    mPSI = mTargetConn.prepareStatement(sql_insert);
    mPSI.setString(1, changeID);
    mPSI.setString(2, departement);
    mPSI.setString(3, anfangszeit);
    mPSI.setString(4, endzeit);
    mPSI.setString(5, freigabe);
    int rows = mPSI.executeUpdate();

    System.out.println("Anzahl INSERTS: " + rows);
 
    mPSI.close();

    String sql_getID = "SELECT [ID] FROM [" + mTablesAndColumns[1] + "] WHERE " + getWhere();
    System.out.println("SQL-Statement: " + sql_getID);
    mPSL = mTargetConn.prepareStatement(sql_getID);
    mPSL.setString(1, changeID);
    mPSL.setString(2, departement);
    ResultSet rs = mPSL.executeQuery();
    while (rs.next()) {
      id = rs.getLong("ID");
    }//end while
    System.out.println("ID = " + id);
   
    rs.close();
    mPSL.close();

    String sql_update = "UPDATE [" + mTablesAndColumns[1] + "] SET [Change ID] = ? WHERE [ID] = ?";
    System.out.println("SQL-Statement: " + sql_update);
    mPSU = mTargetConn.prepareStatement(sql_update);
    mPSU.setString(1, "Update:" + changeID);
    mPSU.setString(2, String.valueOf(id));
    rows = mPSU.executeUpdate();

    System.out.println("Anzahl UPDATE: " + rows);

    mPSU.close();

    String sql_changeID = "SELECT [Change ID] FROM [" + mTablesAndColumns[1] + "] WHERE [ID] = ?";
    System.out.println("SQL-Statement: " + sql_changeID);
    mPSL = mTargetConn.prepareStatement(sql_changeID);
    mPSL.setString(1, String.valueOf(id));
    ResultSet rsi = mPSL.executeQuery();
    while (rsi.next()) {
      changeID = rsi.getString("Change ID");
    }//end while
    System.out.println("ID = " + changeID);

    rsi.close();

    mPSL.close();

    String sql_del = "DELETE FROM [" + mTablesAndColumns[1] + "] WHERE " + getWhere();
    System.out.println("SQL-Statement: " + sql_del);
    mPSU = mTargetConn.prepareStatement(sql_del);
    mPSU.setString(1, changeID);
    mPSU.setString(2, departement);
    rows = mPSU.executeUpdate();

    System.out.println("Anzahl DELETE: " + rows);

    mPSU.close();

    System.out.println("Test1 done!\n\n");
  }

2. Der Verdacht, dass eine mit SharePoint verlinkte Tabelle nur über den Autowert updatet werden kann hat sich als falsch erwiesen. In der Where Clausel kann man nach beliebigen Spalten und Werten suchen.

3. Die Fehlermeldungen in den Exception sagen dir alles nur nicht wo das Problem liegt. Wie so oft war's ganz einfach. Ich habe die PreparedStatements nicht geschlossen und das führt wohl dazu, dass der Treiber oder die DB da was durcheinander bringt (Ev gibts dazu auch eine Restriktion die ich erst jetzt kennen gelernt habe...). Ich war mir bewusst, dass es nur ein ResultSet pro Statement geben kann, aber, dass es nur ein offenes PreparedStatement pro Connection geben darf habe ich verpasst :oops:

Somit ist die Sache mit einem simplen
Java:
mPSI.close();
nach dem ausführen erledigt. :eek:

Mein Konzept, die PreparedStatements als Members abzulegen und wieder zu verwenden, muss ich nun über den Haufen werfen. Naja halb so wild, erzeuge ich die PreparedStatements halt jedesmal neu.

Grüsse
Nahum77
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
V SQLite java.sql.SQLException: no such column: Datenbankprogrammierung 18
D MySQL SQLException time zone value is unrecognized Datenbankprogrammierung 2
M Oracle SQLException: Verbindung getrennt Datenbankprogrammierung 2
S MySQL SQLException Parameter index out of range (1 > number of parameters, which is 0). Datenbankprogrammierung 10
B Probleme mit java.sql.SQLException: ResultSet closed Datenbankprogrammierung 21
nrg Oracle java.sql.SQLException Ungültiger Vorgang bei schreibgeschützter Ergebnismenge Datenbankprogrammierung 0
N SQL-Statement SQLException: the '|' object Datenbankprogrammierung 3
Y java.sql.SQLException: [Microsoft][ODBC Driver Manager] Invalid cursor state Datenbankprogrammierung 2
H Derby/JavaDB SQLException wenn die Datenbank in eine Jar gepackt wurde. Datenbankprogrammierung 6
I java.sql.SQLException: No data found Datenbankprogrammierung 3
T java.sql.SQLException: unexpected end of statement Datenbankprogrammierung 2
H java.sql.SQLException: Access denied for user 'root'@'localhost' (using password : YES) Datenbankprogrammierung 1
D getConnection mit SQLException Datenbankprogrammierung 7
F SQLException fangen beim verbinden mit Hibernate Datenbankprogrammierung 17
D java.sql.SQLException Datenbankprogrammierung 3
S SQLException: No suitable driver bei DB2 Datenbankprogrammierung 4
J Einstellungen für die Ausnahme SQLException Datenbankprogrammierung 7
M java.sql.SQLException: Unable to open file Datenbankprogrammierung 2
M java.sql.SQLException: out of memory Datenbankprogrammierung 18
zilti java.sql.SQLException: Before start of result set Datenbankprogrammierung 2
C FM: java.sql.SQLException: Geschlossene Ergebnismenge: next Datenbankprogrammierung 7
A Problem: java.sql.SQLException Datenbankprogrammierung 5
I hilfe! java.sql.SQLException Datenbankprogrammierung 7
M java.sql.SQLException: No data found Datenbankprogrammierung 9
K MsAccess immer beim zweiten Update java.sql.SQLException Datenbankprogrammierung 28
C SQLException wenn String auf VARCHAR geschrieben wird Datenbankprogrammierung 10
G SQLException: Lässt sich der Fehler feststellen? Datenbankprogrammierung 10
R MySQL denies access to data source - java.sql.SQLException Datenbankprogrammierung 14
L SQLException --> Übersetzung nötig! Datenbankprogrammierung 2
G SQLException: No operations allowed after connection closed Datenbankprogrammierung 2
K java.sql.SQLException: Before start of result set Datenbankprogrammierung 2
R SQL Exception: Cursor position not valid Datenbankprogrammierung 7
Aruetiise MySQL Name JDBC Drive finden Datenbankprogrammierung 4
S Name aus der Datenbank bekommen Datenbankprogrammierung 2
F Oracle The parameter name [...] in the query's selection criteria does not match any parameter name d Datenbankprogrammierung 2
B JDBC-Connection: Data source name too long Datenbankprogrammierung 3
D Derby/JavaDB java.lang.ClassFormatError: Duplicate field name&signature Datenbankprogrammierung 3
G Auf Oracle Schema Name zugreifen Datenbankprogrammierung 7
R Wie ist URL zu meiner MySQL Datenbank? Name?Pwd? Datenbankprogrammierung 2
T HILFE: MySQL und tomcat-5.5.4 == Name jdbc is not bound in t Datenbankprogrammierung 3
G SELECT Name= " " verhindern Datenbankprogrammierung 5

Ähnliche Java Themen

Neue Themen


Oben