PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : C# Regex oder StrReplace


JasonX
2016-04-27, 09:06:04
Hallo,

ich suche eine möglichkeit Sonderzeichen auszukommentieren für SQL-Statements in C#.

Ich habe ein kleines Tool, das eine kleine Datenbank aus einem DataGridView Element befüllen soll.
Als SQL-Server verwenden wir MS-SQL.
Dieses Tool bricht mir jedesmall beim zurückschreiben in eine andere Datenbank weg.
Hier mal ein Sniplet des Codes der betroffen ist:

Regex Funktion:

public static string SQLEscape(string sValue)
{
// SQL Encoding: r, n, x00, x1a, Backslash, einfache und doppelte Hochkommas
if (sValue == null) return null;
else return Regex.Replace(sValue, @"[-rnx00x1a\'""_\@]", @"$0");
}


Insert-Aktion bei Button-Click Event:

private void cmd_bestuecken_Click(object sender, EventArgs e)
{
SqlConnection updatedb = new SqlConnection();
updatedb.ConnectionString = @"Data Source=servername;Initial Catalog=updatedb;User ID=username;Password=password";
//updatedb.Open();

string updatequery;
using (SqlCommand update = new SqlCommand())
{
update.Connection = updatedb;
updatedb.Open();
for(int i=0; i< dataGridView1.Rows.Count;i++)
{
updatequery = @"INSERT INTO Kunden VALUES ("
+ dataGridView1.Rows[i].Cells["Kundennummer"].Value + ", "
+ dataGridView1.Rows[i].Cells["Kundenname"].Value + ", "
+ dataGridView1.Rows[i].Cells["Kundenmail"].Value + ", "
+ dataGridView1.Rows[i].Cells["Telefon"].Value + ");";
update.CommandText = SQLEscape(updatequery);
update.ExecuteNonQuery();
updatedb.Close();

}

}
}


Im Anhang der Fehler der kommt wenn ich diesen Code ausführe.
Ich vermute das Problem liegt bei den Sonderzeichen.
Hier in dem Fehler liegt es wahrscheinlich am "-".
Jedoch greift der Regex nicht wirklich.

Anhang 2 ist die SQL-Tabelle in die geschrieben werden soll.

MfG
Jason

Gast
2016-04-27, 09:58:33
Schrecklicher code:
Variablennamen und Funktionen sind schlecht gewaehlt.
Warum nur die eingeschobenen Klammern?
Und warum verwendest du kein LINQ/InsertAllOnSubmit?

Und bist du dir sicher, das das so gewollt ist:

updatedb.Open();
for(int i=0; i< dataGridView1.Rows.Count;i++)
{
...
updatedb.Close();
}

JasonX
2016-04-27, 10:21:46
Hi,

mir ist bewusst, das der Code nicht der schönste und beste ist.
Ich bin leider kein Anwendungsentwickler und sehe mich da noch eher als
Anfänger, da alles nach Learning by Doing und Recherche abläuft.
Deshalb bitte ich hier erstmal um Nachsicht.

Welche eingeschobenen klammern?

Das Open und Close der Connection war eigentlich zuerst in der Schleife.
Ich verstand aber nicht warum er immer auf und zu machen soll, statt zu öffnen und nach abarbeitung der Schleife zu schließen.
Das Close hab ich nur übersehen und noch in der Schleife vergessen.
Falls du dass meinst.

Gast
2016-04-27, 10:28:15
Probiers mit InsertAllOnSubmit und einer Class Kunde, das sollte das escapen automatisch übernehmen.

PatkIllA
2016-04-27, 10:28:38
Den ganzen Escape Krams sofort vergessen und auf DbParameter setzen. Alles andere ist Müll und führt zu Sicherheitslücken. Das gehört in jedes SQL Tuturial in den ersten Absatz.

Monger
2016-04-27, 11:32:58
Im Anhang der Fehler der kommt wenn ich diesen Code ausführe.
Ich vermute das Problem liegt bei den Sonderzeichen.
Hier in dem Fehler liegt es wahrscheinlich am "-".
Jedoch greift der Regex nicht wirklich.

Bindestriche haben in Charakterklassen in Regex spezielle semantische Bedeutung. Das hier: [A-F]+ bedeutet: matche auf jeden String der aus Buchstaben zwischen A und F (also A, B, C, D, E, F) besteht. Wenn du den Unterstrich in einer Charakterklasse capturen willst, musst du ihn escapen: [A\-F] matcht NUR strings die die Zeichen A, F oder Bindestrich enthalten.

Davon abgesehen hat PatkIllA natürlich völlig recht: SQL Queries per String zusammenzuzimmern lädt zu SQL Injections ein, und ist damit eine der banalsten und gefährlichsten Sicherheitslücken überhaupt. Wenn du jetzt den Code da anfasst, bist du für den Kack ab sofort verantwortlich. Den Schuh würde ich mir nicht anziehen: entweder richtig machen, oder es jemandem geben der es richtig macht. Alles andere ist fahrlässig.

Exxtreme
2016-04-27, 11:46:36
2 Anmerkungen noch:

1. return null ist böse, zumindest in Java weil das zu überraschenden NullPointerExceptions führen kann. Ich weiss zwar nicht ob das ein Problem in .NET ist aber machen würde ich sowas nicht.

2. Der Kunde-Tabelle würde ich eine echte Identitätsspalte spendieren. Da tun sich SQL Server viel leichter damit.

Godmode
2016-04-27, 11:58:15
Den ganzen Escape Krams sofort vergessen und auf DbParameter setzen. Alles andere ist Müll und führt zu Sicherheitslücken. Das gehört in jedes SQL Tuturial in den ersten Absatz.

@Threadstarter:
Hier die Erklärung: http://stackoverflow.com/questions/7505808/why-do-we-always-prefer-using-parameters-in-sql-statements

JasonX
2016-04-27, 15:24:34
OK,
ich hab den ganzen Codeteil jetzt auf SqlParameters umgestellt.
Dadurch hab ich mir, wie vorhergesagt, das Escapen gespart.

Und paar Codezeilen.
Danke :)

Monger
2016-04-27, 19:12:10
2 Anmerkungen noch:

1. return null ist böse, zumindest in Java weil das zu überraschenden NullPointerExceptions führen kann. Ich weiss zwar nicht ob das ein Problem in .NET ist aber machen würde ich sowas nicht
Ist selbstverständlich in allen Hochsprachen böse, es sei denn man kennzeichnet es entsprechend (TryGetQuery z.B.)