alcuni dettagli su come il codice si comporta in fase di esecuzione:
// This line declares a variable named Values and sets its value to
// a new array of strings. However, this new array is never used
// because the loop overwrites Values with a new array before doing
// anything else with it.
string[] Values = new string[3];
foreach (string line1 in lines)
{
Values = line1.Split(';');
// At this point in the code, whatever was previously stored in Values has been
// tossed on the garbage heap, and Values now contains a brand new array containing
// the results of splitting line1 on semicolons.
// That means that it is no longer safe to assume how many elements the Values array has.
// For example, if line1 is blank (which often happens at the end of a text file), then
// Values will be an empty array, and trying to get anything out of it will throw an
// exception
string query = "INSERT INTO demooo VALUES ('" + Values[0] + "','" + Values[1] + "','" + Values[2] + "')";
cmd = new SqlCommand(query,con);
cmd.ExecuteNonQuery();
}
Simile a come Valori mantiene sempre sovrascritti, che SqlCommand
che si crea al di fuori del ciclo sarà anche mai abituarsi. È sicuro inserire entrambe le dichiarazioni all'interno del ciclo. Il seguente codice lo fa, e aggiunge anche qualche controllo degli errori per assicurarsi che un numero utilizzabile di valori sia stato recuperato dalla linea. Salterà semplicemente le righe che non sono abbastanza lunghe - se ciò non va bene, potrebbe essere necessario creare un codice di gestione degli errori più complesso.
foreach(string line in lines)
{
string[] values = line.split[';'];
if(values.Length >= 3)
{
string query = "INSERT INTO demooo VALUES ('" + Values[0] + "','" + Values[1] + "','" + Values[2] + "')";
using (SqlCommand command = new SqlCommand(query, con))
{
cmd.ExecuteNonQuery();
}
}
}
Come una nota finale, il codice di cui sopra potrebbe essere vulnerabile agli hacker se si sta utilizzando in qualcosa di simile a un'applicazione Web. Pensate a cosa potrebbe avere il comando inviato al server se si stesse elaborando un file che si presentava così:
1;2;3
4;5;6
7;8;9') DROP TABLE demooo SELECT DATALENGTH('1
Un'opzione più sicura è quella di utilizzare query con parametri, che vi aiuterà a proteggere contro questo tipo di attacco. Lo fanno separando il comando dai suoi argomenti, che aiuta a proteggerti dal passare in valori per argomenti che assomigliano al codice SQL. Un esempio di come impostare le cose in questo modo sarebbe più simile a questo:
string query = "INSERT INTO demooo VALUES (@val1, @val2, @val3);
using (var command = new SqlCommand(query, con))
{
command.Parameters.AddWithValue("@val1", Values[0]);
command.Parameters.AddWithValue("@val2", Values[1]);
command.Parameters.AddWithValue("@val3", Values[2]);
command.ExecuteNonQuery();
}
+1 per menzionare l'iniezione SQL. Tuttavia, il testo nella domanda dell'OP è diviso per spazi (non per le interruzioni di riga come nel tuo esempio), il che rende gli attacchi di questo tipo molto più difficili. –
In realtà credo che sarebbe meglio per l'OP fare un inserto batch. Ancora, +1 per una risposta molto ben dettagliata. – Crono