I'm doing an app with C# in which I wanna have a button so the user can insert lots of data into the database using a .CSV file. I managed to insert by reading the .CSV file but if I'm trying to insert with an ID that already exists I get an exception and I want it to replace the existent one with the new data.
This is the method that I'm using right now which inserts only if it doesn't already exist
private async Task ProcessCsvData(string file)
{
string csvData = File.ReadAllText(file);
string[] rows = csvData.Split('\n');
using (SqlConnection connection = new SqlConnection(connectionString))
{
await connection.OpenAsync();
using (SqlTransaction transaction = connection.BeginTransaction())
{
try
{
bool skipFirstIteration = true;
foreach(string row in rows)
{
if(skipFirstIteration)
{
skipFirstIteration = false;
continue;
}
if (string.IsNullOrEmpty(row))
continue;
string[] columns = row.Split(',');
string query = "INSERT INTO alumnos(id_alumno, nombre, apellidos, sexo, dni, nie, fecha_nacimiento, " +
"localidad_nacimiento, provincia_nacimiento, nombre_correspondencia, domicilio, localidad, provincia, telefono, " +
"movil, codigo_postal, tutor1, dni_tutor1, tutor2, dni_tutor2, pais, nacionalidad, email_alumno, email_tutor1, " +
"email_tutor2, telefono_tutor1, telefono_tutor2, movil_tutor1, movil_tutor2, apellido1, apellido2, tipo_dom, ntutor1, ntutor2, nss, qr, cod_tarjeta) " +
"VALUES (@id_alumno, @nombre, @apellidos, @sexo, @dni, @nie, @fecha_nacimiento, @localidad_nacimiento, @provincia_nacimiento, " +
"@nombre_correspondencia, @domicilio, @localidad, @provincia, @telefono, @movil, @codigo_postal, @tutor1, @dni_tutor1, @tutor2, " +
"@dni_tutor2, @pais, @nacionalidad, @email_alumno, @email_tutor1, @email_tutor2, @telefono_tutor1, @telefono_tutor2, @movil_tutor1, " +
"@movil_tutor2, @apellido1, @apellido2, @tipo_dom, @ntutor1, @ntutor2, @nss, @qr, @cod_tarjeta)";
var parameters = new DynamicParameters();
parameters.Add("@id_alumno", int.Parse(columns[0].Trim()));
parameters.Add("@nombre", columns[1].Trim());
parameters.Add("@apellidos", columns[2].Trim());
parameters.Add("@sexo", char.Parse(columns[3].Trim()));
parameters.Add("@dni", columns[4].Trim());
parameters.Add("@nie", columns[5].Trim());
parameters.Add("@fecha_nacimiento", DateTime.ParseExact(columns[6].Trim(), "dd/MM/yyyy", CultureInfo.InvariantCulture));
parameters.Add("@localidad_nacimiento", columns[7].Trim());
parameters.Add("@provincia_nacimiento", columns[8].Trim());
parameters.Add("@nombre_correspondencia", columns[9].Trim());
parameters.Add("@domicilio", columns[10].Trim());
parameters.Add("@localidad", columns[11].Trim());
parameters.Add("@provincia", columns[12].Trim());
parameters.Add("@telefono", columns[13].Trim());
parameters.Add("@movil", columns[14].Trim());
parameters.Add("@codigo_postal", columns[15].Trim());
parameters.Add("@tutor1", columns[16].Trim());
parameters.Add("@dni_tutor1", columns[17].Trim());
parameters.Add("@tutor2", columns[18].Trim());
parameters.Add("@dni_tutor2", columns[19].Trim());
parameters.Add("@pais", columns[20].Trim());
parameters.Add("@nacionalidad", columns[21].Trim());
parameters.Add("@email_alumno", columns[22].Trim());
parameters.Add("@email_tutor1", columns[23].Trim());
parameters.Add("@email_tutor2", columns[24].Trim());
parameters.Add("@telefono_tutor1", columns[25].Trim());
parameters.Add("@telefono_tutor2", columns[26].Trim());
parameters.Add("@movil_tutor1", columns[27].Trim());
parameters.Add("@movil_tutor2", columns[28].Trim());
parameters.Add("@apellido1", columns[29].Trim());
parameters.Add("@apellido2", columns[30].Trim());
parameters.Add("@tipo_dom", columns[31].Trim());
parameters.Add("@ntutor1", columns[32].Trim());
parameters.Add("@ntutor2", columns[33].Trim());
parameters.Add("@nss", columns[34].Trim());
parameters.Add("@qr", columns[35].Trim());
parameters.Add("@cod_tarjeta", columns[36].Trim());
connection.Execute(query, parameters, transaction);
}
transaction.Commit();
}
catch (Exception e)
{
transaction.Rollback();
Console.WriteLine($"Error inserting into database: {e.Message}");
}
}
}
}
This is what I'm trying to do in order to replace the existent one if it doesn't exist. I changed the query to MERGE but doesn't seem to work since I get this exception: "Exception thrown: 'Microsoft.Data.SqlClient.SqlException' in Microsoft.Data.SqlClient.dll."
private async Task ProcessCsvData(string file)
{
string csvData = File.ReadAllText(file);
string[] rows = csvData.Split('\n');
using (SqlConnection connection = new SqlConnection(connectionString))
{
await connection.OpenAsync();
using (SqlTransaction transaction = connection.BeginTransaction())
{
try
{
bool skipFirstIteration = true;
foreach(string row in rows)
{
if(skipFirstIteration)
{
skipFirstIteration = false;
continue;
}
if (string.IsNullOrEmpty(row))
continue;
string[] columns = row.Split(',');
//string query = @"MERGE INTO alumnos AS target
// USING (VALUES (@id_alumno, @nombre, @apellidos, @sexo, @dni, @nie, @fecha_nacimiento,
// @localidad_nacimiento, @provincia_nacimiento, @nombre_correspondencia,
// @domicilio, @localidad, @provincia, @telefono, @movil, @codigo_postal,
// @tutor1, @dni_tutor1, @tutor2, @dni_tutor2, @pais, @nacionalidad,
// @email_alumno, @email_tutor1,
// @email_tutor2, @telefono_tutor1, @telefono_tutor2, @movil_tutor1, @movil_tutor2,
// @apellido1, @apellido2, @tipo_dom, @ntutor1, @ntutor2, @nss, @qr, @cod_tarjeta))
// AS source (id_alumno, nombre, apellidos, sexo, dni, nie, fecha_nacimiento,
// localidad_nacimiento, provincia_nacimiento, nombre_correspondencia,
// domicilio, localidad, provincia, telefono, movil, codigo_postal,
// tutor1, dni_tutor1, tutor2, dni_tutor2, pais, nacionalidad, email_alumno,
// email_tutor1, email_tutor2, telefono_tutor1, telefono_tutor2, movil_tutor1, movil_tutor2,
// apellido1, apellido2, tipo_dom, ntutor1, ntutor2, nss, qr, cod_tarjeta)
// ON target.id_alumno = source.id_alumno
// WHEN MATCHED THEN
// UPDATE SET target.nombre = source.nombre,
// target.apellidos = source.apellidos,
// target.sexo = source.sexo,
// target.dni = source.dni,
// target.nie = source.nie,
// target.fecha_nacimiento = source.fecha_nacimiento,
// target.localidad_nacimiento = source.localidad_nacimiento,
// target.provincia_nacimiento = source.provincia_nacimiento,
// target.nombre_correspondencia = source.nombre_correspondencia,
// target.domicilio = source.domicilio,
// target.localidad = source.localidad,
// target.provincia = source.provincia,
// target.telefono = source.telefono,
// target.movil = source.movil,
// target.codigo_postal = source.codigo_postal,
// target.tutor1 = source.tutor1,
// target.dni_tutor1 = source.dni_tutor1,
// target.tutor2 = source.tutor2,
// target.dni_tutor2 = source.dni_tutor2,
// target.pais = source.pais,
// target.nacionalidad = source.nacionalidad,
// target.email_alumno = source.email_alumno,
// target.email_tutor1 = source.email_tutor1,
// target.email_tutor2 = source.email_tutor2,
// target.telefono_tutor1 = source.telefono_tutor1,
// target.telefono_tutor2 = source.telefono_tutor2,
// target.movil_tutor1 = source.movil_tutor1,
// target.movil_tutor2 = source.movil_tutor2,
// target.apellido1 = source.apellido1,
// target.apellido2 = source.apellido2,
// target.tipo_dom = source.tipo_dom,
// target.ntutor1 = source.ntutor1,
// target.ntutor2 = source.ntutor2,
// target.nss = source.nss,
// target.qr = source.qr,
// target.cod_tarjeta = source.cod_tarjeta
// WHEN NOT MATCHED THEN
// INSERT (id_alumno, nombre, apellidos, sexo, dni, nie, fecha_nacimiento, localidad_nacimiento, provincia_nacimiento,
// nombre_correspondencia, domicilio, localidad, provincia, telefono, movil, codigo_postal, tutor1, dni_tutor1,
// tutor2, dni_tutor2, pais, nacionalidad, email_alumno, email_tutor1, email_tutor2, telefono_tutor1,
// telefono_tutor2, movil_tutor1, movil_tutor2, apellido1, apellido2, tipo_dom, ntutor1, ntutor2, nss, qr, cod_tarjeta)
// VALUES (@id_alumno, @nombre, @apellidos, @sexo, @dni, @nie, @fecha_nacimiento, @localidad_nacimiento,
// @provincia_nacimiento, @nombre_correspondencia, @domicilio, @localidad, @provincia, @telefono, @movil,
// @codigo_postal, @tutor1, @dni_tutor1, @tutor2, @dni_tutor2, @pais, @nacionalidad, @email_alumno,
// @email_tutor1, @email_tutor2, @telefono_tutor1, @telefono_tutor2, @movil_tutor1, @movil_tutor2,
// @apellido1, @apellido2, @tipo_dom, @ntutor1, @ntutor2, @nss, @qr, @cod_tarjeta)";
var parameters = new DynamicParameters();
parameters.Add("@id_alumno", int.Parse(columns[0].Trim()));
parameters.Add("@nombre", columns[1].Trim());
parameters.Add("@apellidos", columns[2].Trim());
parameters.Add("@sexo", char.Parse(columns[3].Trim()));
parameters.Add("@dni", columns[4].Trim());
parameters.Add("@nie", columns[5].Trim());
parameters.Add("@fecha_nacimiento", DateTime.ParseExact(columns[6].Trim(), "dd/MM/yyyy", CultureInfo.InvariantCulture));
parameters.Add("@localidad_nacimiento", columns[7].Trim());
parameters.Add("@provincia_nacimiento", columns[8].Trim());
parameters.Add("@nombre_correspondencia", columns[9].Trim());
parameters.Add("@domicilio", columns[10].Trim());
parameters.Add("@localidad", columns[11].Trim());
parameters.Add("@provincia", columns[12].Trim());
parameters.Add("@telefono", columns[13].Trim());
parameters.Add("@movil", columns[14].Trim());
parameters.Add("@codigo_postal", columns[15].Trim());
parameters.Add("@tutor1", columns[16].Trim());
parameters.Add("@dni_tutor1", columns[17].Trim());
parameters.Add("@tutor2", columns[18].Trim());
parameters.Add("@dni_tutor2", columns[19].Trim());
parameters.Add("@pais", columns[20].Trim());
parameters.Add("@nacionalidad", columns[21].Trim());
parameters.Add("@email_alumno", columns[22].Trim());
parameters.Add("@email_tutor1", columns[23].Trim());
parameters.Add("@email_tutor2", columns[24].Trim());
parameters.Add("@telefono_tutor1", columns[25].Trim());
parameters.Add("@telefono_tutor2", columns[26].Trim());
parameters.Add("@movil_tutor1", columns[27].Trim());
parameters.Add("@movil_tutor2", columns[28].Trim());
parameters.Add("@apellido1", columns[29].Trim());
parameters.Add("@apellido2", columns[30].Trim());
parameters.Add("@tipo_dom", columns[31].Trim());
parameters.Add("@ntutor1", columns[32].Trim());
parameters.Add("@ntutor2", columns[33].Trim());
parameters.Add("@nss", columns[34].Trim());
parameters.Add("@qr", columns[35].Trim());
parameters.Add("@cod_tarjeta", columns[36].Trim());
connection.Execute(query, parameters, transaction);
}
transaction.Commit();
}
catch (Exception e)
{
transaction.Rollback();
Console.WriteLine($"Error inserting into database: {e.Message}");
}
}
}
}
I tried using a REPLACE query instead of the INSERT but I'm using MSSQL and for what I know that doesn't exist.
Any ideas why the query doesn't work? The connectionString and everything seems to be correct but the query.
1条答案
按热度按时间wqnecbli1#
your code has performance problem because you connect to DB per Record CSV
Has a lot of way for your problem(First #1 is better way)
#1.
first :import CSV To Temp Table on sql server With C#
then Create A procedure that code procedure is merge final table with Temp Table
#2.
first:Load Data CSV and Send data of CSV to procedure with User-Defined Table Type
then :merge final table with "input procedure is Table Type" in procedure
#3.
Load Data CSV in Ram and merge with final table in Memory
#4.Use SSIS
UseFullLink: Passing a List of Values to a Stored Procedure from C# https://gavilan.blog/2022/04/20/passing-a-list-of-values-to-a-stored-procedure-from-c/
Using MERGE in SQL Server: https://www.mssqltips.com/sqlservertip/1704/using-merge-in-sql-server-to-insert-update-and-delete-at-the-same-time/