none
Consulta sql RRS feed

  • Pregunta

  • Buenas tardes, trabajo con SQL y C#, alguien me ayuda como puedo recuerar el ultimo numero insertado en una tabla maestro para poder grabar el id en la tabla detalle.

    Yo actualmente lo hago mediante una consulta SELECT TOP 1 idVENTA FROM ventas order by idVenta desc

    Pero algunas veces me guarda en otro detalle porque justo en el mismo momento guardan otra fila.

    Saludos

    lunes, 17 de febrero de 2020 18:46

Todas las respuestas

  • Deleted
    lunes, 17 de febrero de 2020 18:59
  • Yo utilizo el SCOPE_IDENTITY
    INSERT INTO ESQUEMA.TABLA
                    (ADICIONADO_POR, 
                     FECHA_ADICION
                    )
                    VALUES
                    (@I_USUARIO_AUT, 
                     @V_FECHA_ADICION
                    );
                    IF(@@ROWCOUNT > 0)
                        BEGIN
                            SET @O_SECUENCIAL = SCOPE_IDENTITY();
                            SET @O_EXITO = 1;
                            SET @O_MENSAJE = 'La información fue registrada correctamente.';
                    END;
                        ELSE
                        BEGIN
                            SET @O_RESULTADO_INT = 0;
                            SET @O_EXITO = 0;
                            SET @O_MENSAJE = 'La información no pudo ser registrada.';
                    END;
    En la variable @O_SECUENCIAL se guarda el ID (identity) del registro insertado
    lunes, 17 de febrero de 2020 19:02
  • Hola Mauricio Hamak:

    El problema no es recuperar el idVenta, ya que tal cual lo haces, lo puedes envolver en una transacción y con un nivel de aislamiento Serializable, y nadie podría escribir en esa transación.

    A mi modo de ver el problema esta en como insertas en el maestro, porque de tú mensaje entiendo que estas recuperando el útlimo solicitándolo desde c# y luego insertas. Y ese es el problema.

    Deberías de insertar y recuperar el valor insertado, para luego poder insertar los detalles siempre contra ese valor recuperado.

    Un pequeño ejemplo

    create table maestro
    ([id]    int, 
     [valor] varchar(10)
    );
    go
    CREATE PROCEDURE SP_MAX 
    (
    	@ID INT OUT,
        @VALOR VARCHAR(4)
    )
    AS
    BEGIN
    BEGIN TRY
    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
     
    BEGIN TRANSACTION
    
    	SET @ID =  (SELECT MAX(ID)+1 FROM MAESTRO);
    	INSERT INTO MAESTRO (ID, VALOR)
    		VALUES
    			(@ID, @VALOR);
    
    COMMIT TRANSACTION
    END TRY
    BEGIN CATCH
        IF @@TRANCOUNT > 0 
            ROLLBACK TRANSACTION;
        THROW;
    END CATCH
    END
    GO

    La ejecución del mismo.

    DECLARE @ID INT;
    EXEC SP_MAX @ID OUT, @VALOR ='EJEMPLO'
    SELECT @ID 

    En c# la única diferencia es que el parámetro @ID lo tienes que definir al igual que en Sql como OUT.

    https://docs.microsoft.com/es-es/dotnet/csharp/language-reference/keywords/out-parameter-modifier

    No importa recuperarlo con max o con top. sino que este envuelto en una transacción que bloque el registro. Para que otra transacción antes de la inserción no recupere el mismo.

    Otra opción es utilizar una tabla alternativa.

    https://javifer2.wordpress.com/2019/11/23/id-incremental-como/

    lunes, 17 de febrero de 2020 19:03