SQL Server Problem

Für allgemeine Fragen zur Programmierung mit PureBasic.
Cläusel
Beiträge: 25
Registriert: 14.08.2010 21:26
Computerausstattung: PB5.73 Win10 64bit
Wohnort: Oberland

SQL Server Problem

Beitrag von Cläusel »

Aloha,

Ich habe grad die ehrenvolle Aufgabe, eine recht große Datenbankanwendung von MySQL auf SQL Server 2019 umzustricken, /:->
Jetzt scheint da aber die Reihenfolge des Auslesens einer Rolle zu spielen.. wie schon in einem früheren Beitrag beschrieben: :o
https://www.purebasic.fr/english/viewtopic.php?t=46564

Wenn ich die Reihenfolge beachte, passt alles. Ist aber nicht der Sinn der Sache: 8)

Code: Alles auswählen

   UseODBCDatabase()
   If OpenDatabase(0, "TESTDSN", "", "")
      If DatabaseQuery(0, "SELECT * FROM Table WHERE RESERVATION_ID = 3925")
         If NextDatabaseRow(0)
            Debug GetDatabaseString(0, DatabaseColumnIndex(0, "Column_1")) ;>> OK
            Debug GetDatabaseString(0, DatabaseColumnIndex(0, "Column_2")) ;>> OK
            Debug GetDatabaseString(0, DatabaseColumnIndex(0, "Column_3")) ;>> OK
            Debug GetDatabaseString(0, DatabaseColumnIndex(0, "Column_4")) ;>> OK
            Debug GetDatabaseString(0, DatabaseColumnIndex(0, "Column_5")) ;>> OK
            Debug GetDatabaseString(0, DatabaseColumnIndex(0, "Column_6")) ;>> OK
          EndIf
          FinishDatabaseQuery(0)
      EndIf
      CloseDatabase(0)
   EndIf
wenn ich jetzt aber zuerst Spalte 6 lese, sind alle anderen Spalte(<6) leer:

Code: Alles auswählen

   UseODBCDatabase()
   If OpenDatabase(0, "TESTDSN", "", "")
      If DatabaseQuery(0, "SELECT * FROM Table WHERE RESERVATION_ID = 3925")
         If NextDatabaseRow(0)
            Debug GetDatabaseString(0, DatabaseColumnIndex(0, "Column_6")) ;>> OK
            Debug GetDatabaseString(0, DatabaseColumnIndex(0, "Column_1")) ;>> Leer
            Debug GetDatabaseString(0, DatabaseColumnIndex(0, "Column_2")) ;>> Leer
            Debug GetDatabaseString(0, DatabaseColumnIndex(0, "Column_3")) ;>> Leer
            Debug GetDatabaseString(0, DatabaseColumnIndex(0, "Column_4")) ;>> Leer
            Debug GetDatabaseString(0, DatabaseColumnIndex(0, "Column_5")) ;>> Leer
          EndIf
          FinishDatabaseQuery(0)
      EndIf
      CloseDatabase(0)
   EndIf
kennt mittlerweile jemand die Ursache... (ich vermute ja einer der 645509738098 Einstellmöglichkeiten von SQL Server)
:freak:

Gruß Cläusel
Benutzeravatar
kpeters58
Beiträge: 25
Registriert: 16.12.2014 18:51

Re: SQL Server Problem

Beitrag von kpeters58 »

Dieser Satz aus der Online-Hilfe stimmt mich da nachdenklich:

Note: This function can be called only once for each column. Therefore if this value needs to be used more than once, the data has to be stored in a variable, since all subsequent calls will return the wrong value. This is an ODBC limitation.

Um zu sehen, ob evtl. ODBC Schuld an Deinem Dilemma ist, könntest Du ja Deinen geposteten Code kurz mal auf SQLite umstellen, um zu sehen, ob das Problem dort auch existiert...

Weiterhin frage ich mich, warum Du den Umweg über DatabaseColumnIndex nimmst, da Du die Spaltennamen zu kennen scheinst - also warum nicht einfach:

Code: Alles auswählen

 Debug GetDatabaseString(0, "Column_1") 
Cläusel
Beiträge: 25
Registriert: 14.08.2010 21:26
Computerausstattung: PB5.73 Win10 64bit
Wohnort: Oberland

Re: SQL Server Problem

Beitrag von Cläusel »

Hallo kpeters58,

Erstmal Danke für deine Antwort,

Das GetDatabaseString() nur einmal je Index aufgerufen werden darf, wusste ich. Aber nicht, das die Reihenfolge wichtig ist.

Das ganze lief zu Anfang auf SQlite... Nachdem das dann zu viele User wurden, ist auf MySQL umgestellt worden.
Aber da das in der Firma jetzt mehr unterstützt wird, soll's jetzt SQL Server werden. Erst da taucht dieses Problem auf.

Das lief seit 12 Jahren Problemlos, auch mit den DatabaseColumnIndex(0, "Column_5") und auch die Reihenfolge war egal.
Mit DatabaseColumnIndex war bei manchen Abfragen einfach übersichtlicher, wenn man das einer Variablen Zuweist
(Dein "GetDatabaseString(0, "Column_1") " geht ja nicht, weil der Index verlangt wird.. GetDatabaseString(0,1))

Code: Alles auswählen

 
 Debug GetDatabaseString(0, 4) ;>> OK
 Debug GetDatabaseString(0, 1) ;>> Leer
 Debug GetDatabaseString(0, 2) ;>> Leer
 Debug GetDatabaseString(0, 3) ;>> Leer
Und noch eines ist mir aufgefallen:
Wird z.B. GetDatabaseString(0,1) direkt als Parameter an eine Prozedur übergeben, ist das darin auch leer. (Nur SQL Server)

Code: Alles auswählen

MeineProzedur(GetDatabaseString(0,1))
Andere Probleme habe ich noch nicht entdeckt.
Das muss ich jetzt erstmal so hinnehmen und 40000 Codezeilen durchforsten.

Aber die Suchfunktionen von PB sind da Klasse.. wird klappen..

Gruß Cläusel
Benutzeravatar
kpeters58
Beiträge: 25
Registriert: 16.12.2014 18:51

Re: SQL Server Problem

Beitrag von kpeters58 »

Oops - das hätte natürlich

Code: Alles auswählen

GetDatabaseString(0, #COLUM_NAME)
sein sollen! Ich benutze an dieser Stelle immer Konstanten, um besser gegen Schemaänderungen gewappnet zu sein.

Ich habe mein halbes Leben mit MS SQL Server verbracht (und Du hast recht: MS sollte sich endlich mal trauen, Settings auszumisten!) und mir ist noch nie was untergekommen, was Deine Beobachtungen hervorgerufen hätte.

Ich denke nach wie vor, daß ODBC Deine Probleme verursacht - hast Du mal kurz auf Firebird oder Interbase umgeschaltet, um zu sehen, ob Dein Problem persistiert oder ob es wirklich auf MS beschränkt ist?
Benutzeravatar
kpeters58
Beiträge: 25
Registriert: 16.12.2014 18:51

Re: SQL Server Problem

Beitrag von kpeters58 »

Hmm, Du hast wider Erwarten Recht! Habe mal eben Interbase ausprobiert und kann dort problemlos die Spalten "rückwärts" auslesen ...
Sehr seltsam...

Code: Alles auswählen

UseODBCDatabase()
user.s = "sysdba"
pass.s = "masterkey"
If OpenDatabase(0, "InterbaseODBC", user, pass, #PB_Database_ODBC)
  If DatabaseQuery(0, "SELECT * FROM test WHERE id = 2")
    If NextDatabaseRow(0)
      Debug GetDatabaseString(0, DatabaseColumnIndex(0, "Col3")) ;>> OK
      Debug GetDatabaseString(0, DatabaseColumnIndex(0, "Col2")) ;>> OK
      Debug GetDatabaseString(0, DatabaseColumnIndex(0, "Col1")) ;>> OK
    EndIf
    FinishDatabaseQuery(0)
 EndIf
 CloseDatabase(0)
EndIf
Cläusel
Beiträge: 25
Registriert: 14.08.2010 21:26
Computerausstattung: PB5.73 Win10 64bit
Wohnort: Oberland

Re: SQL Server Problem

Beitrag von Cläusel »

Hier in der Firma sind nicht so viele ODBC Treiber installiert.
MySQL über ODBC hat dieses Problem nicht. Auch das alte
Acess *mdb nicht. Nur eben SQL Server ODBC.
Ist aber auch das erste mal, das ich (nach Acess) mit MS was mache.
(Und mal ganz ehrlich.. Das mit den Datum und den Ländereinstellungen bei SQLserver hab ich noch nicht gerafft. Das ist ja praktisch unmöglich, ein Datum in der jeweiligen richtigen Syntax abzufragen...)

Hab daheim noch localDB installiert (welches mal ein nicht aufgeblasenes MS Produkt ist und super zum Entwickeln... ) und das in verschiedenen Versionen. Immer das gleiche.
Jetzt mache ich nicht sooo viel mit Datenbanken.
Bin eher Richtung "alles Mögliche" z.B. CAN/LIN ect..
Aber ich werd da einfach mal meinen Programmierstil etwas strukturierter machen, um die nötige Reihenfolge
einzuhalten... Wenn man es weiss, das man drauf achten muss, geht das schon irgendwie...
Deinen Tip mit den Konstanten muss ich mal durchdenken... Danke dafür.

Ich werd bei Gelegenheit mal eine andere Programmiersprache ausprobieren und
schauen, ob das da auch so ist...
Benutzeravatar
kpeters58
Beiträge: 25
Registriert: 16.12.2014 18:51

Re: SQL Server Problem

Beitrag von kpeters58 »

Letzteres kannst Du Dir sparen - habe es soeben in Lazarus durchgezogen - es funktioniert einwandfrei: Auf derselben Maschine, mit demselben Treiber, DSN etc. etc.

Man muß also wohl Purebasic schuldig sprechen! Du solltest das als Bug melden und kannst dazu gerne meinen Code verwenden.

Hier der Pascal Code:

Code: Alles auswählen

procedure TestForm.button_QueryClick(Sender: TObject);
var
  s:     String;
  conn:  TODBCConnection;
  query: TSQLQuery;
  trans: TSQLTransaction;

begin
  conn  := TODBCCOnnection.Create(nil);
  query := TSQLQuery.Create(nil);
  trans := TSQLTransaction.Create(nil);
  try
    try
      conn.DatabaseName   := 'SQL_EXPRESS';
      conn.UserName       := 'kpeters';
      conn.Password       := 'iwed';
      conn.Transaction    := trans;
      query.DataBase      := conn;
      query.SQL.Text      := 'select * from test ';
      query.Open;
      S := '';
//    while not query.EOF do
      begin
        s := s + query.FieldByName('Col3').AsString + #13;
        s := s + query.FieldByName('Id').AsString   + #13;
        s := s + query.FieldByName('Col1').AsString + #13;
        s := s + query.FieldByName('Col2').AsString + #13;
//      query.Next;
      end;
    finally
      query.Free;
      conn.Free;
      trans.Free;
    end;
  except
    on E:Exception do
      ShowMessage(E.Message);
  end;
  memo_Log.Text := S;
end;
Antworten