Create Stored Procedure to fill a table

1

I have a mobile application that calls different services that I have in c# with Wcf . The issue is that I have one of those services in which the user from the mobile sends an object called Medicion . This object has a list of CeldaKeyValUpload .

public class Medicion
{
    [DataMember]
    public string medicion_user_email { get; set; }
    [DataMember]
    public string medicion_user_nombre { get; set; }
    [DataMember]
    public string medicion_app_os { get; set; }
    [DataMember]
    public string medicion_app_version { get; set; }
    [DataMember]
    public string medicion_latitud { get; set; }
    [DataMember]
    public string medicion_longitud { get; set; }
    [DataMember]
    public string medicion_sala_id { get; set; }
    [DataMember]
    public string medicion_codigo_empresa { get; set; }
    [DataMember]
    public string medicion_codigo_cadena { get; set; }
    [DataMember]
    public string medicion_codigo_modulo { get; set; }
    [DataMember]
    public string medicion_categoria_codigo { get; set; }
    [DataMember]
    public List<CeldaKeyValUpload> celdas { get; set; }
}

Y

public class CeldaKeyValUpload
{
    [DataMember]
    public int celda_id { get; set; }
    [DataMember]
    public string celda_key_codigo { get; set; }
    [DataMember]
    public string celda_key_valor { get; set; }
}

The list that can reach me from the mobile can be very extensive, say an example 200 records. In my database I have two tables one called MedicionEncabezado and MedicionDetalle . In the first table, everything of class Medicion is saved except the list CeldaKeyValUpload , since it is saved in MedicionDetalle .

The problem I have is that I put myself in the case that for any reason the mobile loses internet and can not upload these 200 records. For this I have created temporary tables called TmpMedicionEncabezado and TmpMedicionDetalle . When the device sends the data, it loads these temporary tables, and once it finishes successfully, the load fills my official tables with the data . This is why I need to create a Stored Procedure that is responsible for passing the data from the temporary tables to the official tables. Why do I do this? To not fill my junk data table.

The problem I have is that I do not know how to get the data from the temporary tables and save them in the official tables. I still do not handle much in sql-server-2005 .

    
asked by sioesi 09.11.2016 в 23:33
source

2 answers

2

Instead of temporary tables, use a transaction.

The use of a transaction allows you to make several changes to the data in your tables by means of several SQL statements, but the changes are applied to the database in an atomic manner. In other words, either all the changes are applied to your database, or none is applied. But it is not possible that only a part of the changes are applied, which could cause corruption of the data. In effect, the use of a transaction allows several operations to be carried out as if they had been carried out in a single operation.

In order for your changes to be part of a transaction, you must run SqlConnection.BeginTransaction() to indicate where the transactions that are part of the transaction begin, and SqlTransaction.Commit() or SqlTransaction.Rollback() to indicate where it ends. Commit confirms that you want all changes to be applied from one to the database, and Rollback indicates that you want to discard all the changes you have made since the transaction began.

Here is a model of how you can use a transaction to avoid corruption of your data in case of error. Try adding an artificial error that occurs in the middle of the transaction and you will see that you will not find partial junk data in your database.

using (var conn = new SqlConnection("..."))
{
    conn.Open();

    // transacción empieza aquí.
    using (var tx = conn.BeginTransaction())
    {
        bool exito = false;

        try
        {
            // digamos que tienes que insertar varias entidades
            // uno por uno en un ciclo por medio de un stored procedure.
            foreach (var entidad in listaDeEntidades)
            {
                using (var cmd = new SqlCommand(
                    "insertarEntidad",
                    conn,
                    tx))
                {
                    cmd.CommandType = CommandType.StoredProcedure;

                    cmd.Parameters.Add("@param1", SqlDbType.VarChar).Value = entidad.Propiedad;
                    // ...
                    // otros parámetros
                    // ...

                    // Aquí, el cambio se manda a la base de datos,
                    // pero queda en "stand by", por decirlo así,
                    // hasta que hagas el "commit" final más abajo
                    // después de completar todos los cambios.
                    cmd.ExecuteNonQuery();
                }
            }

            // Si alcanzamos este punto, quiere decir que no hubo ningún error
            // y que podemos hacer el commit (confirmacón final).
            // De lo contrario, hay que hacer un Rollback.
            exito = true;
        }
        finally
        {
            if (exito)
            {
                // Confirma todos los cambios hechos dentro de la transacción.
                // Es como si hubiéramos hecho todos los cambios de un solo.
                tx.Commit();
            }
            else
            {
                // Si exito == false, significa que surgió un error
                // durante la transacción. Rollback descarta todos los cambios
                // hechos durante la transacción hasta este punto.
                tx.Rollback();
            }
        }
    }
}
    
answered by 10.11.2016 / 03:55
source
2

I do not know how you send the data, but if you send them all together and with a single call to the web service, it should not do anything until the upload is completed, that is, if the connection is cut off, it should not be triggered. web service method. Put a break point, do the test and tell us. I hope it helps. Greetings!

    
answered by 10.11.2016 в 00:56