Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
SQL String Handling
Kriz
myCSharp.de - Member



Dabei seit:
Beiträge: 115

Themenstarter:

SQL String Handling

beantworten | zitieren | melden

Verwendetes Datenbanksystem: SQL

Moin zusammen,

ich hab eine API, die auf eine SQL Datenbank zugreift. Insgesamt sind es grob 300 verschiedenste Abfragen.
Lange Abfragen, die im Code schwer zu lesen sind, habe ich als StoredProcedur angelegt, kürzere Abfragen direkt im Code.
Beim Refactoring ist mir dieses Durcheinander aufgefallen un dich überlege, ob es nicht bessere Lösungen gibt?!
Beispielsweise könnte man ja die Strings auch in eine separate TXT ablegen und abrufen, oder eine statische Klasse nutzen...

Wie handhabt ihr Eure SQL Queries?
private Nachricht | Beiträge des Benutzers
Stefan.Haegele
myCSharp.de - Member

Avatar #avatar-3068.jpg


Dabei seit:
Beiträge: 462
Herkunft: Untermeitingen

beantworten | zitieren | melden

Also ich habe dazu eine eigene Klasse - im Code ist nur der Befehl zum Nachladen der Befehle fest hinterlegt. Alle anderen Befehle liegen in der Datenbank und werden entweder beim Start oder bei Bedarf nachgeladen.
private Nachricht | Beiträge des Benutzers
ClaraSoft
myCSharp.de - Member



Dabei seit:
Beiträge: 48

beantworten | zitieren | melden

Guten Morgen,

Also ich habe auch schon oft darüber nachgedacht wie ich das bei meinen Service machen sollte. Die Idee die Sql Queries in einer txt/sql/json Datei zu hinterlegen hatte ich auch schon. Bin aber letztlich zu dem Schluss gekommen, dass das keine gute Idee ist und zwar aus dem ganz einfachen Grund, das jemand die Datei manipulieren könnte. Die Queries in der Datenbank zu speichern halte aus den selben Grund auch für eine schlechte Idee.

Von Dapper gibt es Beispielsweise einen SQL Builder -> https://www.nuget.org/packages/Dapper.SqlBuilder/
Oder du nutzt wieder ganz klassisch das Entity Framework.

Es gibt sicherlich noch mehr Möglichkeiten das Problem anzugehen.

Grüße
private Nachricht | Beiträge des Benutzers
Palladin007
myCSharp.de - Member

Avatar #avatar-4140.png


Dabei seit:
Beiträge: 1.786
Herkunft: Düsseldorf

beantworten | zitieren | melden

Warum nicht als embedded resource?

Oder ein Repository, dessen Implementierung größtenteils aus SQL besteht.
Das Ausführen und Mappen übernimmt z.B. Dapper.

Oder direkt ein vollwertiges ORM wie EFCore, dann spart man sich die ganzen SQL Queries.
private Nachricht | Beiträge des Benutzers
BerndFfm
myCSharp.de - Team

Avatar #nZo9Gyth4VPDSxGqM4sT.jpg


Dabei seit:
Beiträge: 3.765
Herkunft: Frankfurt a.M.

beantworten | zitieren | melden

Das wollte ich auch schreiben.

Ich schreibe keinen SQL Code mehr, sondern lasse das vom ORM machen. So ist alles aufgeräumt, typsicher und selbstdokumentierend.

Weiterentwicklung und Fehlersuche ist auch viel einfacher.



Alt : if (such_ar_bez1 != "") sqlstr += "ar_bez1 LIKE '" + such_ar_bez1.ToSqlString() + "' AND ";

Neu : if (such_ar_bez1 != "") qry = qry.ar_bez1().IsLike(such_ar_bez1).And();


Das ist jetzt ein eigenes ORM, jetzt würde ich aber Dapper oder EF benutzen.

Grüße Bernd
Workshop : Datenbanken mit ADO.NET
Xamarin Mobile App : Finderwille Einsatz App
Unternehmenssoftware : Quasar-3
private Nachricht | Beiträge des Benutzers
Palladin007
myCSharp.de - Member

Avatar #avatar-4140.png


Dabei seit:
Beiträge: 1.786
Herkunft: Düsseldorf

beantworten | zitieren | melden

Zitat von BerndFfm
Das ist jetzt ein eigenes ORM, jetzt würde ich aber Dapper oder EF benutzen.

Wobei Dapper aber das SQL schreiben nicht ab nimmt - zumindest nach meinem letzten Stand.
Es mappt nur die Ergebnisse passend zu den eigenen Klassen.
Das übernehmen nur die "großen ORMs" wie EF oder nHibernate, sind dadurch aber auch deutlich komplexer.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Palladin007 am .
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15.854

beantworten | zitieren | melden

Zitat von Kriz
Wie handhabt ihr Eure SQL Queries?
Wenn es Request Queries sind: alles über EF Core (selten Dapper), sehr viel über entsprechend indizierte Queries.
Wenn es Round Trip Queries sind: über Stored Procs (über EFCore Connection), sofern es MSSQL ist.

Genau über den Weg ist auch das Forum hier umgesetzt; universell einsetzbar.
private Nachricht | Beiträge des Benutzers
gfoidl
myCSharp.de - Team

Avatar #avatar-2894.jpg


Dabei seit:
Beiträge: 6.830
Herkunft: Waidring

beantworten | zitieren | melden

Hallo,

auch wenn "Alt" davor steht
Zitat

Alt : if (such_ar_bez1 != "") sqlstr += "ar_bez1 LIKE '" + such_ar_bez1.ToSqlString() + "' AND ";
der dringende Hinweis zu [Artikelserie] SQL: Parameter von Befehlen.
So ist es ein Musterbeispiel für SQL-Injection

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"
private Nachricht | Beiträge des Benutzers
BerndFfm
myCSharp.de - Team

Avatar #nZo9Gyth4VPDSxGqM4sT.jpg


Dabei seit:
Beiträge: 3.765
Herkunft: Frankfurt a.M.

beantworten | zitieren | melden

Zitat von gfoidl
So ist es ein Musterbeispiel für SQL-Injection

Hab ich mir gedacht dass das gleich auffällt.

Das habe ich ungefähr im Jahr 2004 geschrieben, da gab es den guten Artikel noch nicht.

In der Extension 'ToSqlString()' habe ich zwar versucht alles rauszufiltern was zu Fehlern oder Missbrauch führen kann, hat aber nicht immer funktioniert.

Das eigene ORM arbeitet natürlich mit Parametern.

Grüße Bernd
Workshop : Datenbanken mit ADO.NET
Xamarin Mobile App : Finderwille Einsatz App
Unternehmenssoftware : Quasar-3
private Nachricht | Beiträge des Benutzers
Th69
myCSharp.de - Experte

Avatar #avatar-2578.jpg


Dabei seit:
Beiträge: 4.359

beantworten | zitieren | melden

Intern machen die Parameter aber auch nichts anderes als die besonderen Zeichen (z.B. ') zu escapen (habe ich auch schon selber geschrieben).
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15.854

beantworten | zitieren | melden

Also da passiert schon deutlich mehr als nur Zeichen rausfiltern/escapen....
SqlCommand Source Code
Da wird völlig Typ-gerecht ein vollständiges Cleanup und Aufbau des SQL Befehls vorgenommen.
private Nachricht | Beiträge des Benutzers
Th69
myCSharp.de - Experte

Avatar #avatar-2578.jpg


Dabei seit:
Beiträge: 4.359

beantworten | zitieren | melden

Ich meinte konkret den Code zur Umwandlung der Parameter bei der Erzeugung des SQL-Befehls. Dort werden dann u.a. diese Hilfsmethoden aus SqlServerEscapeHelper verwendet:


/// <summary>
///  Escape a string to be used inside TSQL literal, such as N'somename' or 'somename'
/// </summary>
static internal string EscapeStringAsLiteral(string input) {
    Debug.Assert(input != null, "input string cannot be null");
    return input.Replace("'", "''");
}

/// <summary>
/// Escape a string as a TSQL literal, wrapping it around with single quotes.
/// Use this method to escape input strings to prevent SQL injection 
/// and to get correct behavior for embedded quotes.
/// </summary>
/// <param name="input">unescaped string</param>
/// <returns>escaped and quoted literal string</returns>
static internal string MakeStringLiteral(string input) {
    if (ADP.IsEmpty(input)) {
        return "''";
    }
    else {
        return "'" + EscapeStringAsLiteral(input) + "'";
    }
}
Ähnlich sieht es dann bei den anderen Datenbanken (Oracle, PostGres, ...) aus.
Datenbanken nehmen ja (leider) nur direkt SQL-Strings entgegen, d.h. diese müssen vom Client aus zusammengesetzt werden (auch wenn vom Anwender Parameter verwendet werden).
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Th69 am .
private Nachricht | Beiträge des Benutzers