Seite 1 von 1

Fehler cursor update nach append

Verfasst: Do, 17. Nov 2016 17:05
von Rudolf
Hallo,
habe ein Problem beim Updaten eines Cursors nach dem append. Es steht in der Fehlermeldung ein Feld welches überhaupt nicht betroffen ist.

SQLState: 42000, ErrorCode:1064
[MySQL][ODBC 3.51 Driver][mysqld-5.1.73]You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT LAST_INSERT_ID()' at line 1

Thread ID 1
Called from SQLSTATEMENT:EXECUTE(522)
Called from SQLSELECT:EXECUTE(1703)
Called from SQLSELECT:UPDATEROW(2100)
Called from MAIN(38)

SQLString: insert into statistik1(`_syncts`) values ( NULL); SELECT LAST_INSERT_ID()

Mein Code:

Code: Alles auswählen

     oCursor := oConn:Cursor("SELECT * FROM statistik1")
     oCursor:Execute()
     if !(oCursor:UsePositionDelete .and. oCursor:UsePositionUpdate)
          oCursor:SetPrimaryKey("_SYNCID") // numeric, autoincrement,
     endif

     oCursor:append()
     oCursor:updaterow()
die Connection ist read/write, über die gleiche kann ich problemlos die Tabelle mit create table anlegen.
Das Feld _syncts ist ein normales char(11) Feld ohne Extras, kann also auch NULL sein. Primarykey Feld _SYNCID ist PK NN AI, kann also auch nicht Schuld sein.
Wenn ich das SQL Statement aber in der MySQLWorkbench eingebe und ausführe, funktioniert es einwandfrei. Der Syntax ist also ok.
Hat jemand eine Idee ?
Grüße
Rudolf

Re: Fehler cursor update nach append

Verfasst: Do, 17. Nov 2016 23:25
von AUGE_OHR
Rudolf hat geschrieben:...
[MySQL][ODBC 3.51 Driver][mysqld-5.1.73]
...
Wenn ich das SQL Statement aber in der MySQLWorkbench eingebe und ausführe, funktioniert es einwandfrei. Der Syntax ist also ok.
ich denk das die WB native die libmysql.DLL anspricht und nicht über ODBC arbeitet.

probiere es doch mal mit der lates Connector/ODBC 5.3.6 Version von https://dev.mysql.com/downloads/connector/odbc/

Re: Fehler cursor update nach append

Verfasst: Fr, 18. Nov 2016 7:55
von Rudolf
Hallo Jimmy,
danke, werds versuchen. Angeblich soll der MariaDB Treiber auch funktionieren, gibt jetzt eine 32 Bit Version, werde auch diesen Testen, soll stabiler sein. Interessant ist dass es über ein Statement funktioniert:

Code: Alles auswählen

  aData := array(2)
    oStmt := oConn:NewStatement()
    oStmt:SQLString := 'INSERT INTO statistik1(objekt,alter1w) VALUES (?,?)'
    oStmt:Prepare()
   for i := 1 to 3
      aData[1] := LTrim(Str(i))
      aData[2] := LTrim(Str(i))
      oStmt:Execute( aData )
   next
Hat also mit dem Cursor zu tun und nicht mit der Tabelle oder connection.

Ich brauche aber immer sofort die autoincrement ID, und das wird sicher langsam wenn ich immer ein SQL statement nach einem execute ausführe mit LastIDSyntax. Wäre auch kein Problem ein INSERT statement zu bauen und LastIDSyntax anhängen, aber wie bekomme ich die ID sofort zurück im Statement ? Ich könnte
SET @lastid = LAST_INSERT_ID();
oder
SELECT @lastid1 := LAST_INSERT_ID();
anhängen, aber wie bekomme ich @lastid sofort als Variable sofort zurück ?
Es geht zwar mit einem Cursor ()

Code: Alles auswählen

oCursor := oConn:Cursor("SELECT LAST_INSERT_ID()")
oCursor:Execute()
nIDRet := oCursor:fieldget(1)
aber ich denke die Kombination Statement und Cursor ist zu langsam bei vielen Datensätzen. Muss doch eine einfachere Lösung geben. Im SQLEXPRESS Forum hat zumindest einer schon das gleiche Problem gemeldet, Boris dürfte schon auf der Suche sein.
Grüße
Rudolf

Re: Fehler cursor update nach append

Verfasst: Fr, 18. Nov 2016 10:30
von Rudolf
Hallo,
habe das nächste Problem. Habe die Struktur eines Feldes von int(10) auf int(15) geändert, in der MySQL Workbench sehe ich die neue Größe korrekt, wenn ich aber mit SQLEXPRESS die Struktur prüfe, bekomme ich immer die alte Größe von 10. Habe beide Rechner rebootet und auch Treiber auf letzten Stand (5.3) gebracht, keine Änderung. Wenn ich aber den Typ von einem Feld ändere, kennt es SQLEXPRESS korrekt. Keine Ahnung woher die alten Werte kommen.
Mal schauen was Boris schreibt.
Grüße
Rudolf

Re: Fehler cursor update nach append

Verfasst: Sa, 19. Nov 2016 8:35
von Rudolf
Hallo,
hab ein Beispiel, auf verschienden Servern getestet, Cursor und Änderung in der Tabelle funktioniert nicht
Grüße
Rudolf

Code: Alles auswählen

#include "sql.ch"
#include "sqlext.ch"

#define __CONNECT_STRING  "DRIVER=MySQL ODBC 3.51 Driver;SERVER=xxx;DATABASE=test;UID=xxx;PWD=xxx;"


//-----------------------------------------------------------------------------
Procedure DbeSys(); Return // don't need to load any of Alaska's database drivers

//-----------------------------------------------------------------------------
Procedure Main()
   Local i, oConn, oStmt, oCursor, aData[2]

   SQLConnection():displayErrors := .f.
   oConn := SQLConnection():new()

   // first try to connect to the MS Access TEST.MDB database, if that fails then
   // display all ODBC data sources available on user's machine and allow user to select one

   if !oConn:driverConnect(nil, __CONNECT_STRING, SQL_DRIVER_NOPROMPT) ;
      .and. !oConn:DriverConnect()
      MsgBox("Unable to connect to data source!")
      oConn:destroy()
      Return
   endif

   ? "Connected to: ", oConn:DbmsName, ", Database: ", oConn:DatabaseName

   SQLConnection():displayErrors := .t.

   oStmt := oConn:NewStatement()
   oStmt:DisplayErrors := .t.
   cSQL := "CREATE TABLE IF NOT EXISTS statistik1(SYNCID INT(10) NOT NULL PRIMARY KEY AUTO_INCREMENT, objekt int(10) DEFAULT NULL, alter1w int(10) DEFAULT NULL, alter2w int(10) DEFAULT NULL, SYNCTS char(11) DEFAULT NULL) ENGINE=InnoDB;"
   oStmt:SQLString := cSQL
   if oStmt:Execute() == SQL_XPP_ERROR
      ? "error creating table"
   endif

   cSQL := "ALTER TABLE statistik1(CHANGE alter2w alter2w int(15));"
   if oStmt:Execute() == SQL_XPP_ERROR
      ? "error modify table"
   endif
     // Tabel is not modified !!!!!!!!!!!!!!!!!!!!!

   cSQL := "ALTER TABLE statistik1(CHANGE SYNCTS SYNCTS char(15));"
   if oStmt:Execute() == SQL_XPP_ERROR
      ? "error modify table"
   endif
     // Tabel is not modified !!!!!!!!!!!!!!!!!!!!!

     oCursor := oConn:Cursor("SELECT * FROM statistik1")
     oCursor:LastIDSyntax := NIL
     oCursor:Execute()

     if !(oCursor:UsePositionDelete .and. oCursor:UsePositionUpdate)
          oCursor:SetPrimaryKey("SYNCID")
     endif

   for i := 1 to oCursor:FCount()
      oCol := oCursor:GetSQLColumn(i)
      ? Str(i,3), PadR(oCol:Name,36), oCol:ValType, Str(oCol:Length,10,0), Str(oCol:Decimals,9,0), space(5), oCol:isSearchable, space(10), oCol:isUpdatable
   next


     oCursor:append()
     oCursor:updaterow()
     if oCursor:rowsupdated = SQL_XPP_ERROR
          ? "Fehler update row"
     else
          ? oCursor:fieldget("SYNCID")

          ? oCursor:fieldpos("objekt")
          ? oCursor:fieldpos("SYNCID")



          oCursor:fieldput(2,1)
          oCursor:fieldput("objekt",1)

          ? "value:" + str(oCursor:fieldget("objekt"))


          oCursor:updaterow()
          if oCursor:rowsupdated = SQL_XPP_ERROR
               ? "Fehler update objekt"
          endif
          oCursor:commit() // !!!!!!!!!!!!!!!!!!!!! only the autoincrement field is filled, all ohter are empty !!!!!!!!!

     endif


     aData := array(2)
        oStmt := oConn:NewStatement()

    oStmt:SQLString := 'INSERT INTO statistik1(objekt,alter1w) VALUES (?,?)'

   oStmt:Prepare()

   for i := 1 to 3
      aData[1] := LTrim(Str(i))
      aData[2] := LTrim(Str(i))
      oStmt:Execute( aData )
   next
     // all data is written correct to the table
   oStmt:Destroy()


   ? "disconnecting..."
   oConn:destroy()    // this will also drop the cursor
   wait

   Return