|
Von:Matthias Kahlert usenet@max-pro.de An:Tom Knauf knauf@pdtgmbh.de |
||||
erstellt am:21.02.2018 02:10:29
- #23696 in section
Antworten Antworten mit Zitat
--from Newsreader at Mittwoch, 21. Februar 2018; 02:10:29-- Am 16.02.2018 um 16:11 schrieb Tom Knauf: > Bei Uebergabe als Parameter an ODBC > > weiss nicht moeglich, bei Literalen schon. > https://xkcd.com/327/ > https://www.explainxkcd.com/wiki/index.php/Little_Bobby_Tables > https://www.easysoft.com/developer/sql-injection.html Das ist mit ein Hauptgrund, warum ich zu 99,999% mit Parametern arbeite. Ich muss mich damit nicht um SQL Injection kümmern, denn die ist dabei nicht möglich, und ich muss mich auch nicht um Sonderzeichen ö.ä. kümmern. Oder was machst Du, wenn ein Firmenname eines Kunden >> [Meine] 'tolle' "Firma" << lautet? -- Matthias |
||||
Von:Matthias Kahlert usenet@max-pro.de An:Hans-Peter Grözinger hanspetergr@gmx.de :gelesen |
||||
erstellt am:21.02.2018 02:05:03
- #23695 in section
Antworten Antworten mit Zitat
--from Newsreader at Mittwoch, 21. Februar 2018; 02:05:03-- Am 15.02.2018 um 19:01 schrieb Hans-Peter Gr�zinger: > So ganz habe ich das ganze Szenario noch nicht verstanden > > Wie muss denn der SQL-SELECT auf VFP-Seite genau aussehen? > Beispiel: > *-- Kurzzeichen des Benutzers. > lcUser = 'HPG' > lcSQLSelect = 'SELECT VorName, Name FROM tabBenutzer WHERE KurzZeichen = > ?lcUser' > > Ich lasse dann ausführen: > lnResult = SQLEXEC( lnConnection, lcSQLSelect, 'cursResult' ) > > Was passiert denn jetzt bei dem SQLEXEC genau? > > Wandelt der ODBC-Treiber oder die VFP-Funktion SQLEXEC den SELECT noch > um weil ein ? im SELECT steht in: > DECLARE @KurzZeichen CHAR(3) = N'HPG'; > SELECT VorName, Name FROM tabBenutzer WHERE KurzZeichen = @KurzZeichen'; > > Es wäre hilfreich mir hier noch etwas aufs Pferd zu helfen, im > Steigbügel stehe ich schon mal Wenn du die SQL-Server Vollversion installiert hast, findest Du im SSMS im Menü Extras --> SQL Server Profiler. Mit dem Profiler kannst Du quasi die komplette Kommunikation zwischen Server und Client/Applikation mitlesen. Der siehst Du, welche SQL Befehle durchlaufen, wie viel CPU-Zeit die jeweils gebraucht haben, wie viele Reads und Writes, und Du siehst eben auch die echt abgeschickten SQL-Befehl. Aus Deinem Beispiel wird dann sowas wie: exec sp_executesql N'SELECT VorName, Name FROM tabBenutzer WHERE KurzZeichen = @P1 ',N'@P1 varchar(3)','HPG' Er ruft also in Wahrheit eine StoredProcedure auf, an die der SQL-Befehl übergeben wird. Der Parameter wird in ein @P1 umgewandelt, und separat übergeben. Wenn sich also der Parameter ändert, bleibt der SQL-Befehl identisch. Im VFP gibt es statt dem SQLEXEC() übrigens auch noch den SQLPREPARE(), der das SQL-Kommando compiliert ohne es auszuführen, und dann erst mittels SQLEXEC() ausführt (wobei da der Befehl nicht mehr angegeben werden muss). Bei Schleifendurchläufen kann man damit also einfach optimieren. Zum Beispiel: SQLPREPARE(lnHandle, "INSERT INTO tabelle ( test ) VALUES ( ?lnI )") FOR lnI = 1 TO 1000 SQLEXEC(lnHandle) ENDFOR Tipp: Mit dem SQL Profiler kann man auch "Fremdprogramme" mitlesen, was die im SQL Server so machen! Damit kann sogar das SQL Server Management Studio mitlesen, was der im Hintergrund für SQL Befehle absetzt, wenn man beispielsweise ein DB-Backup macht oder Optionen verändert. -- Matthias |
||||
Von:Tom Knauf knauf@pdtgmbh.de An:Tom Knauf knauf@pdtgmbh.de |
||||
erstellt am:16.02.2018 16:11:39
- #23694 in section
Antworten Antworten mit Zitat
--from Newsreader at Freitag, 16. Februar 2018; 16:11:39-- Moin, moin wie Matthias schon beschrieben hat : bei Verwendung von Variablen a la â=80=9C...where kuname = ?m.lckunameâ=80=9D kompiliert der Server die Abfrage und â=80=9Cmerktâ=80=9D sich Statistiken, etc. Bei Verwendung von Literalen macht er das nicht, waere ja auch nicht sinnvoll. Bei Literalen gewinnt der Server Zeit fuer die Abschaetzung (Festwert), verliert aber bei der Statistik und Kompilierung wieder welche. Testen kann man das nicht per Aufruf von Prozeduren, da gelten, vor allem bei lokalen Variablen, wieder andere Werte. Wir mischen das eher locker : Bei hauefig verwendeten Abfragen (FK zu Klartext) nehmen wir Variablen Bei selteneren , vor allem mit vielen Joins, bauen wir den Wert via Textmerge (nur f=C3=BCr numeric pks). Das liegt auch daran dass die SQL-Funktionen zum Update,.. in Funktionen gekapselt sind und diese dann die lokalen Werte der aufrufenden Funktion nicht kennen. cKurz = adrkurz(thisform.oadr.pk_adr) Func adrkurz(nfk) nnfkadr = nfk && private zwischenvariable, nfk ist in sqlwert() nicht bekannt return sqlwert(â=80=9CSelect kurzname from adr where pk_adr = ?m.nnfkadrâ=80=9D,â=80=9Dkurznameâ=80=9D, â=80=9CCUAâ=80=9D) * return sqlwert(â=80=9CSelect kurzname from adr where pk_adr = â=80=9C+Trans(m.nfk),â=80=9Dkurznameâ=80=9D, â=80=9CCUAâ=80=9D) && oder Textmerge endfu Bei Uebergabe als Parameter an ODBC ist eine sqlinjection soweit ich weiss nicht moeglich, bei Literalen schon. https://xkcd.com/327/ https://www.explainxkcd.com/wiki/index.php/Little_Bobby_Tables https://www.easysoft.com/developer/sql-injection.html Wir â=80=9Csanitizenâ=80=9D Felder die zur Suche verwendet werden k=C3=B6nnten (kein â=80=93, ; , kein drop , dele,... im Inhalt) nur zur Sicherheit. Die werden aber eh per variable abgefragt GUPTA scheint da noch anders zu agieren. Gruesse tkn P.S.: "Tom Knauf" --from Newsreader at Donnerstag, 15. Februar 2018; 18:02:18-- http://db-berater.blogspot.de/2014/07/verwendung-von-variablen-statt-literalen.html "Hans-Peter Gr=C3=B6zinger" schrieb im Newsbeitrag news:741070... Hallo Matthias ! -------------------------------------------------------------------------- beim MS-SQLserver soll man mit Variablen arbeiten... Richtig, beim SQL Server soll man immer mit den ?-Variablen arbeiten, denn dann muss der SQL Server den SQL-Befehl nur einmalig kompilieren. Wird der gleiche SQL-Befehl (mit anderem Wert) erneut aufgerufen, kann er den bereits vorkompilierten SQL-Befehl wiederverwenden. -------------------------------------------------------------------------- Hast du da einen Link wo das gut beschrieben ist20 |
||||
Von:Harro Schippan hs@dtsd.de An:Hans-Peter Grözinger hanspetergr@gmx.de :gelesen |
||||
erstellt am:16.02.2018 08:54:21
- #23693 in section
Antworten Antworten mit Zitat
Hi, dieser Artikel bringt da auch noch mal etwas Hintergrund: http://www.db-berater.de/2016/12/abfragen-nicht-mit-variablen-testen/ Was mich jetzt noch irritiert: es hat doch immer geheißen man solle Bind-Variable in Queries verwenden. Ich lese diese Artikel jetzt aber so, daß man mit Literalen die schnellere Lösung hat. Das haben auch meine Test ergeben. Wobei die gravierenden Zeitunterschiede nur bei meiner großen Tabelle ( mehr als 800.000 Datensätze ) zum Tragen kommen. Der GUPTA-Server verwendet bei der Bind-Variablen keinen INDEX. Beim Literal wird der Index verwendet. Neueste Messung mit verschiedenen Werten: Mit Bind-Variable mehr als 22 Sekunden Mit Literal 0,016 Sekunden Ich habe die zeitkritischen Statements mit TEXTMERGE <<Suchbegriff>> auf Literale umgestellt. Die Benutzer sind begeistert. Gruß Harro |
||||
Von:Hans-Peter Grözinger hanspetergr@gmx.de An:Tom Knauf knauf@pdtgmbh.de |
||||
erstellt am:15.02.2018 19:01:10
- #23692 in section
Antworten Antworten mit Zitat
Hallo Tom !
Danke für diesen Link So ganz habe ich das ganze Szenario noch nicht verstanden Wie muss denn der SQL-SELECT auf VFP-Seite genau aussehen? Beispiel: *-- Kurzzeichen des Benutzers. lcUser = 'HPG' lcSQLSelect = 'SELECT VorName, Name FROM tabBenutzer WHERE KurzZeichen = ?lcUser' Ich lasse dann ausführen: lnResult = SQLEXEC( lnConnection, lcSQLSelect, 'cursResult' ) Was passiert denn jetzt bei dem SQLEXEC genau? Wandelt der ODBC-Treiber oder die VFP-Funktion SQLEXEC den SELECT noch um weil ein ? im SELECT steht in: DECLARE @KurzZeichen CHAR(3) = N'HPG'; SELECT VorName, Name FROM tabBenutzer WHERE KurzZeichen = @KurzZeichen'; Es wäre hilfreich mir hier noch etwas aufs Pferd zu helfen, im Steigbügel stehe ich schon mal -- Hans-Peter |
||||
Von:Tom Knauf knauf@pdtgmbh.de An:Hans-Peter Grözinger hanspetergr@gmx.de :gelesen |
||||
erstellt am:15.02.2018 18:02:18
- #23691 in section
Antworten Antworten mit Zitat
--from Newsreader at Donnerstag, 15. Februar 2018; 18:02:18-- http://db-berater.blogspot.de/2014/07/verwendung-von-variablen-statt-literalen.html "Hans-Peter Grözinger" Hallo Matthias ! -------------------------------------------------------------------------- beim MS-SQLserver soll man mit Variablen arbeiten... Richtig, beim SQL Server soll man immer mit den ?-Variablen arbeiten, denn dann muss der SQL Server den SQL-Befehl nur einmalig kompilieren. Wird der gleiche SQL-Befehl (mit anderem Wert) erneut aufgerufen, kann er den bereits vorkompilierten SQL-Befehl wiederverwenden. -------------------------------------------------------------------------- Hast du da einen Link wo das gut beschrieben ist20 |
||||
Von:Hans-Peter Grözinger hanspetergr@gmx.de An:Matthias Kahlert usenet@max-pro.de |
||||
erstellt am:15.02.2018 12:35:08
- #23689 in section
Antworten Antworten mit Zitat
Hallo Matthias !
-- Hans-Peter |
||||
Von:Harro Schippan hs@dtsd.de An:Jens Brand foxnews.9.jbrand@spamgourmet.com |
||||
erstellt am:15.02.2018 11:22:44
- #23688 in section
Antworten Antworten mit Zitat
Hallo Jens, danke, werde ich ausprobieren. Gruß Harro |
||||
Von:Jens Brand foxnews.9.jbrand@spamgourmet.com An:Harro Schippan hs@dtsd.de :gelesen |
||||
erstellt am:15.02.2018 09:00:15
- #23687 in section
Antworten Antworten mit Zitat
--from Newsreader at Donnerstag, 15. Februar 2018; 09:00:15-- Hallo Harro, > > Gibt beim MS-SQL-Server eigentlich auch ein Tool mit dem man prüfen kann > wie eine Query abgearbeitet wird? > War bisher noch nicht auf die Idee gekommen. Im Microsoft SQL Server Management Studio gibt es in der Symbolleiste eine Schaltfläche mit dem ToolTip "Tatsächlichen Ausführungsplan einschließen". Wenn du diesen Schalter einschaltest und dann eine Abfrage ausführst, dann bekommst du eine graphische Darstellung, wie die Ausführung ausgesehen hat, sehr informativ. Viele Grüße Jens Brand |
||||
Von:Harro Schippan hs@dtsd.de An:Matthias Kahlert usenet@max-pro.de |
||||
erstellt am:15.02.2018 07:41:49
- #23686 in section
Antworten Antworten mit Zitat
Habe gestern noch mal mit einem GUPTA-Spezialisten an dem Thema gesessen. Dabei haben wir festgestellt, daß der GUPTA-Server bei Benutzung der BindVariablen (?wSuchOrt) nicht mir dem richtigen INDEX arbeitet. Daher kommen die langen AntwortZeiten. Interessant ist, daß bei der Substitution ( <<wSuchOrt>> ) - anstelle der BindVariablen - der richtige INDEX benutzt wird. Der Spezi klärt nun die Ursache mit dem Hersteller. Ich komme erst mal weiter. Aber man muß tatsächlich bei Queries erst mal prüfen, ob die richtigen Indices benutzt werden. Zumindest bei GUPTA, Möglicherweise ist das auch ein reines GUPTA-Problem. Gruß Harro Gibt beim MS-SQL-Server eigentlich auch ein Tool mit dem man prüfen kann wie eine Query abgearbeitet wird? War bisher noch nicht auf die Idee gekommen. |
||||
Von:Matthias Kahlert usenet@max-pro.de An:Tom Knauf knauf@pdtgmbh.de |
||||
erstellt am:14.02.2018 23:13:55
- #23685 in section
Antworten Antworten mit Zitat
--from Newsreader at Mittwoch, 14. Februar 2018; 23:13:55-- Am 09.02.2018 um 09:36 schrieb Tom Knauf: > Seltsam, beim MS-SQLserver soll man mit Variablen arbeiten... Richtig, beim SQL Server soll man immer mit den ?-Variablen arbeiten, denn dann muss der SQL Server den SQL-Befehl nur einmalig kompilieren. Wird der gleiche SQL-Befehl (mit anderem Wert) erneut aufgerufen, kann er den bereits vorkompilierten SQL-Befehl wiederverwenden. Wenn die Variable bereits als String im SQL-Befehl drinsteht, dann ist jeder SQL-Befehl für den SQL-Server neu, er muss neu kompilieren, neue Statistiken generieren, etc. -- Matthias |
||||
Von:Tom Knauf knauf@pdtgmbh.de An:Harro Schippan hs@dtsd.de :gelesen |
||||
erstellt am:09.02.2018 09:36:36
- #23681 in section
Antworten Antworten mit Zitat
--from Newsreader at Freitag, 9. Februar 2018; 09:36:36-- Hallo Harro, was passiert wenn du die Abfrage umdrehst, also erst den Teil mit dem Year ? Gruesse tom Seltsam, beim MS-SQLserver soll man mit Variablen arbeiten... "Harro Schippan" -------------------------------------------------------------------------- nur hätte ich nicht diesen Geschwindigkeitsunterschied erwartet. -------------------------------------------------------------------------- Hallo Thomas, genau der Geschwindigkeitsunterschied hat mich verwundert. Bin mittlerweile einen Schritt weiter. Es ist so, daß bei "?SuchBegriff" in Verbindung allen Logik-Operatoren außer bei "=" (GLEICH) der GUPTA-Server keine Indices benutzt. Warum das so ist, weiß ich allerdings (noch) nicht. Bekomme jetzt noch ein GUPTA-SQL-Performance-Programm. Das protokolliert alles was auf der GUPTA-Seite während einer QUERY passiert. Ich dachte bisher diese ?-Substitution sei "State of the Art". Hatte bisher damit auch noch kein Problem. Allerdings waren bisher meine Tabellen auch nicht in der Größe. Hier habe ich es mit einer großen Tabelle (viele Felder) mit mehr als 800.000 Datensätzen zu tun. Falls noch jemand was dazu beitragen kann, würde ich mich freuen. Gruß Harro |
||||
Von:Harro Schippan hs@dtsd.de An:Thomas Geissler softart@t-online.de :gelesen |
||||
erstellt am:09.02.2018 09:32:03
- #23680 in section
Antworten Antworten mit Zitat
Hallo Thomas, genau der Geschwindigkeitsunterschied hat mich verwundert. Bin mittlerweile einen Schritt weiter. Es ist so, daß bei "?SuchBegriff" in Verbindung allen Logik-Operatoren außer bei "=" (GLEICH) der GUPTA-Server keine Indices benutzt. Warum das so ist, weiß ich allerdings (noch) nicht. Bekomme jetzt noch ein GUPTA-SQL-Performance-Programm. Das protokolliert alles was auf der GUPTA-Seite während einer QUERY passiert. Ich dachte bisher diese ?-Substitution sei "State of the Art". Hatte bisher damit auch noch kein Problem. Allerdings waren bisher meine Tabellen auch nicht in der Größe. Hier habe ich es mit einer großen Tabelle (viele Felder) mit mehr als 800.000 Datensätzen zu tun. Falls noch jemand was dazu beitragen kann, würde ich mich freuen. Gruß Harro |
||||
Von:Thomas Geissler softart@t-online.de An:Harro Schippan hs@dtsd.de :gelesen |
||||
erstellt am:08.02.2018 17:48:42
- #23679 in section
Antworten Antworten mit Zitat
Hallo Harro, ich würde dieses Verhalten eher als normal abtun nur hätte ich nicht diesen Geschwindigkeitsunterschied erwartet. In der ersten Variante wird wohl jeder Datensatz erst noch mit dem Inhalt der Variable geprüft, während bei der zweiten Variante der zu vergleichende Wert schon feststeht. Gruß Thomas |
||||
Von:Harro Schippan hs@dtsd.de An:All :gelesen |
||||
erstellt am:08.02.2018 16:48:02
- #23678 in section
Antworten Antworten mit Zitat
Hallo zusammen, ich lese über einen ODBC-Treiber in einer GUPTA-Datenbank. Technisch funktioniert es. Aber furchtbar lange Antwortzeiten ( mehr als 25 Sekunden ) Das dauert über 25 Sekunden, IMMER ***************************************************************************** * SQL-Befehl wSuchOrt = LOWER('Köln')+"%" SET TEXTMERGE ON TEXT TO mySQL NOSHOW SELECT KundenNr, Name1, Strasse, Ort, aNum, datgepl FROM stellplatz WHERE (KundenNr = 100311) AND (@LOWER(ort) like ?wSuchOrt) AND (@YEAR(datGepl) = 2015) ENDTEXT retcd = SQLEXEC(gnConnHandleKnG ,mySQL , wCurKnG) ***************************************************************************** Durch Zufall habe ich folgendes probiert Also diesmal beim Suchen nach Ort nicht ?wSuchOrt sondern <<wSuchOrt>>, Das dauert 0,14 Sekunden, auch IMMER. ***************************************************************************** * SQL-Befehl wSuchOrt = LOWER('Köln')+"%" SET TEXTMERGE ON TEXT TO mySQL NOSHOW SELECT KundenNr, Name1, Strasse, Ort, aNum, datgepl FROM stellplatz WHERE (KundenNr = 100311) AND (@LOWER(ort) like '<<wSuchOrt>>') AND (@YEAR(datGepl) = 2015) ENDTEXT retcd = SQLEXEC(gnConnHandleKnG ,mySQL , wCurKnG) ***************************************************************************** Hat jemand eine Idee was diese ResponseZeitUnterschiede bewirkt????? Ich bin total verblüfft. Habe ein paar Batch-Programm, alle samt Langläufer. Das wäre ja eine Revolution bei der Laufzeit. Danke und Gruß Harro |