| Autor |
Beitrag |
flaavia
      
Beiträge: 105
WinXp Vista
D6 Ent, D2007 Ent
|
Verfasst: Do 17.07.03 21:26
Hallo
Ich versuche eine Abfrage von folgendem Muster:
Delphi-Quelltext 1:
| ADOQuery1.SQL.Add('select a, b, c where a = 'irgendwas' order by b ASC'); |
'irgendwas' hat aber selber quotation marks und bringt die string Markierungen vom Anfang und Ende durcheinander.
Was ist hier zu tun ??
Vielen Dank im vorraus für alle Tips
Moderiert von UGrohne: Delphi-Tags eingefügt
|
|
UGrohne
      

Beiträge: 5502
Erhaltene Danke: 220
Windows 8 , Server 2012
D7 Pro, VS.NET 2012 (C#)
|
Verfasst: Fr 18.07.03 00:56
Entweder
Delphi-Quelltext 1:
| ADOQuery1.SQL.Add('select a, b, c where a = ''irgendwas'' order by b ASC'); |
oder
Delphi-Quelltext 1:
| ADOQuery1.SQL.Add('select a, b, c where a = '+QuotedStr('irgendwas')+' order by b ASC'); |
Letzte Variante wohl geschickter, bei Variablen, denn beim ersten hast Du dann 3 einfache Anführungszeichen hintereinander
PS: Das Anführungszeichen vor dem Anführungszeichen (Bsp. 1) wirkt als sogenanntes Escape-Zeichen.
|
|
ShadowThief
      
Beiträge: 278
|
Verfasst: Fr 18.07.03 08:57
aber man macht es doch eigentlich so, oder:
Delphi-Quelltext 1: 2: 3:
| ADOQuery1.SQL.Text :='select a, b, c where a = :VARIABLE order by b ASC'; ADOQuery1.Parameters.ParamByName('VARIABLE').DataType := ftString; ADOQuery1.Parameters.ParamByName('VARIABLE').Value := 'text'; |
dann hat man null stress mit hochkommas und so.
shadow.
|
|
Neuromancer
      
Beiträge: 42
WinNT 4.0 SP6a, WIN 2k Prof SP3, Win XP Prof SP1
D5 Ent, D6 Ent
|
Verfasst: Fr 18.07.03 09:22
| ShadowThief hat folgendes geschrieben: | | aber man macht es doch eigentlich so, oder:. |
Sollte man sich beser nicht angewöhnen. Diese Schreibweise wird anscheinend nicht von allen SQL-Dialekten richtig erkannt.
Unter Oracle soll es z.B. so sein, dass, sobald 2 und mehr Parameter im Spiel sind, Fehlermeldungen auftreten.
Gruß
|
|
ShadowThief
      
Beiträge: 278
|
Verfasst: Fr 18.07.03 09:44
aber ich dachte, die parameter weden von Delphi eingesetzt,
wenn man ADOQuery.Open macht.
also ich glaub nicht, dass die db was von den parameter mitkriegt.
|
|
Neuromancer
      
Beiträge: 42
WinNT 4.0 SP6a, WIN 2k Prof SP3, Win XP Prof SP1
D5 Ent, D6 Ent
|
Verfasst: Fr 18.07.03 09:57
Ich kann dir leider auch nicht sagen, an was es genau liegt. Aber Fakt ist, dass nicht alle Datenbanken mit der :Variable zurechtkommen.
Ich kann hier nur spekulieren: Es ist ja nicht unbedingt gesagt, dass Delphi in diesem Fall generell für die Variable ein 'Variable' einfügt, im Gegenteil, ich denke eher nicht. Denn nicht alle Datenbanken wollen die Delphi-Hochkommas als "Container" für Strings oder Suchausdrücke, manche bevorzugen auch die üblichen Gänsefüßchen ("). Möglicherweise hält hier Delphi erstmal Absprache mit dem zugrunde liegenden Datenbanktreiber/Provider, wobei das eigentlich nicht die Aufgabe von Delphi, sondern der Datenbankengine (ADO, BDE usw.) sein müsste. Hier könnten durchaus Missverständnisse entstehen.
Aber wie gesagt: Das ist nur Spekulation.
Gruß
|
|
ShadowThief
      
Beiträge: 278
|
Verfasst: Fr 18.07.03 10:00
ich weis es auch nicht genau, mir gehts nur darum, schönen code zu haben, deswegen mach ich das immer so. kollegen von mir, bauen ihre sql's auch immer mit + zusammen, ich kann nur das erfahrung sprechen, dass das mit der zeit ziemlich unübersichtlich wird.
aber ... is halt geschmacksache.
|
|
Udontknow
      
Beiträge: 2596
Win7
D2006 WIN32, .NET (C#)
|
Verfasst: Mo 21.07.03 14:52
Hallo!
Shadowthiefs Methode mit den Parametern ist die einzige, die funktioniert. Alles andere lässt den SQL-Parser auf der anderen Seite moppern, denn egal wie Delphi es nun eingefügt hat, die Eigenschaft SQL ist nur ein TStrings-Nachfahre und liefert nur Text, der die SQL-Interpretation dann unmöglich macht.
PS:
Das ist übrigens auch der Grund, wieso manche Datenbanken, die eine schwache Passwortverwaltung haben, so einfach zu umgehen sind.
Benutzername Eingabe: IstVölligEgal
Passwort Eingabe: {' or ''='}
Cu,
Udontknow
Zuletzt bearbeitet von Udontknow am Mo 21.07.03 15:10, insgesamt 3-mal bearbeitet
|
|
UGrohne
      

Beiträge: 5502
Erhaltene Danke: 220
Windows 8 , Server 2012
D7 Pro, VS.NET 2012 (C#)
|
Verfasst: Mo 21.07.03 14:57
@udontknow: Irgendwie versteh ich gerade überhaupt nicht, worauf Du hinaus willst oder was Du mit Deinem Kommentar meinst, oder auf was er sich bezieht 
|
|
Udontknow
      
Beiträge: 2596
Win7
D2006 WIN32, .NET (C#)
|
Verfasst: Mo 21.07.03 14:57
Vielleicht macht es mein PS deutlicher...
Cu,
Udontknow
|
|
UGrohne
      

Beiträge: 5502
Erhaltene Danke: 220
Windows 8 , Server 2012
D7 Pro, VS.NET 2012 (C#)
|
Verfasst: Mo 21.07.03 15:04
OK, jetzt hab ichs begriffen, aber das heißt ja nicht, dass die anderen Methoden nicht funktionieren, sie sind in der reinen Form nur nicht für sowas wie Passwort-eingaben geeignet, weshalb man in diesem Bereich auch etwas anders vorgehen sollte. Da hast Du schon recht....
|
|
Udontknow
      
Beiträge: 2596
Win7
D2006 WIN32, .NET (C#)
|
Verfasst: Mo 21.07.03 15:04
Ich erkläre es ein bisschen :
Wenn jemand einfach ein Statement zusammenbaut, das so aussieht:
select * from benutzertabelle where benutzername=%eingabeBenutzername% and passwort=%eingabepasswort
Und nach der Eingabe ein Stringreplace durchführt, um die Parameter im SQL zu bestücken, steht dann da:
select * from benutzertabelle where benutzername='Administrator' and
Passwort='' or ''=''
Das gilt aber immer, da immer ''='' ist! Voila, login erfolgt.
Cu,
udontknow
|
|
Udontknow
      
Beiträge: 2596
Win7
D2006 WIN32, .NET (C#)
|
Verfasst: Mo 21.07.03 15:07
Sie sind nicht nur für so etwas nicht geeignet. Wenn ein Hochkomma in deinem Parameter vorkommt, kommt der SQL-Parser ins Schleudern:
Quelltext 1:
| SQL: select * from benutzertabelle where benutzername=%eingabebenutzername% |
Benutzername: D'Artagnan
ergibt:
Quelltext 1:
| select * from benutzertabelle where benutzername='D'Artagnan' |
Das ist ungültiges SQL.
Cu,
Udontknow
|
|
UGrohne
      

Beiträge: 5502
Erhaltene Danke: 220
Windows 8 , Server 2012
D7 Pro, VS.NET 2012 (C#)
|
Verfasst: Mo 21.07.03 16:12
OK, das ist ein guter Grund es so zu machen. Werde wohl den Anfängern hier in Zukunft lieber diesen Tipp geben
Aber deswegen muss es nicht unbedingt besser sein, nur eben leichter. Meine Variante ist mir lieber, da ich so volle Kontrolle über die Eingaben und mögliche Fehler haben kann, da mir durch schlichtes Feldwerte-zuweisen und posten zwar so direkt kaum Fehler unterlaufen können.
Aber ich bin eher der Typ, der Fremdkomponenten nicht so traut, denn wenn sich da ein Fehler einschleicht, ist er schwer zu finden und meist noch schwerer zu beheben.
Aber jedem das Seine 
|
|
Neuromancer
      
Beiträge: 42
WinNT 4.0 SP6a, WIN 2k Prof SP3, Win XP Prof SP1
D5 Ent, D6 Ent
|
Verfasst: Mo 21.07.03 17:01
Sorry, aber Hochkommas in einem UserName/Password zuzulassen halte ich nicht für besonders professionell.
Ich denke, man sollte sich hier eher auf die gängigen Konventionen berufen (a..Z, 0..9, und vielleicht noch ein Underscore)
Generell alles zuzulassen was in die ASCII-Tabelle passt, kann einen in Teufels Küche führen. Das würde ja z.B. auch bedeuten, dass ein #0 erlaubt wäre. Was das für eventuell nachfolgende Operationen mit einem PChar bedeutet, kann man sich ja ausmalen. Oder was ist z.B. mit #8?
Gruß
|
|
flaavia 
      
Beiträge: 105
WinXp Vista
D6 Ent, D2007 Ent
|
Verfasst: Di 22.07.03 08:50
tolle Diskussion, viel gelernt.
genau weis ich jetzt allerdings immer noch nicht, welche Methode die beste ist. Ist es sicher, das :variable nicht z.B. bei Oracle funktioniert?
Wäre eigentlich für mich unerheblich, andererseits macht es auch Sinn, sich nur Methoden anzugewöhnen, die man ggf. später universell verwenden kann.
Vielen Dank
|
|
Neuromancer
      
Beiträge: 42
WinNT 4.0 SP6a, WIN 2k Prof SP3, Win XP Prof SP1
D5 Ent, D6 Ent
|
Verfasst: Di 22.07.03 09:30
Ich kann dir nur sagen, dass ich selbst auch die :Variable-Methode bevorzuge, einfach auch aus dem Grund, dass der Code dadurch übersichtlicher ist.
Ich arbeite normalerweise gegen einen MS-SQL-Server, dort gibt es überhaupt keine Probleme. Im September werde ich aber den Job wechseln, dann muss ich gegen eine Pervasive-Datenbank arbeiten. Und hier ist eben nicht sichergestellt, ob die :Variable-Methode funktioniert. Aber das wird sich relativ schnell herausfinden lassen.
Die :Variable-Methode birgt noch eine andere Stolperfalle: Soviel ich weiß, lassen sich dadurch nur Parameter beschreiben, die nach einer WHERE-Klausel kommen; so ist es z.B. nicht möglich den Tabellennamen mit ":Tabelle" in einer SELECT * FROM-Anweisung zu ersetzen.
Die Geschichte mit Oracle habe ich aus einem anderen Forum. Ich selbst habe noch nie gegen Oracle gearbeitet, kann dir deshalb also leider auch nichts genaueres dazu sagen.
Aber an der Geschichte, die Udontknow da anspricht, ist schon was dran...
Gruß
|
|