c# - Generación automática de ID de pedido

CorePress2024-01-25  11

Quería tener una identificación de transacción única para cada pedido realizado en mi sistema y que solo se incrementa una vez. este es el código que estoy usando. ayúdame a arreglar el incremento.

 string transactionCode;
        con = new SqlConnection(@"Data Source=LAPTOP-KA7UGSG3;Initial Catalog=imsysdb;Integrated Security=True");
        cmd = new SqlCommand("SELECT TransactionCode from tblOrders", con);
        con.Open();
        dr = cmd.ExecuteReader();

        if (dr.Read())
        {
            int code = int.Parse(dr[0].ToString()) + 1;
            transactionCode = code.ToString("000");

        }
        else if (Convert.IsDBNull(dr))
        {
            transactionCode = ("001");
        }
        else
        {
            transactionCode = ("001");
        }

        lblTransactionCode.Text = transactionCode.ToString(); 

SALIDA

|código de transacción|

|001| |002| |002| |002|

1

¿Esto responde a tu pregunta? Incremento automático de clave primaria en SQL

- Jeroen van Langen

28 de marzo de 2021 a las 9:53

1

¿Por qué no utilizar simplemente un incremento automático creado por la base de datos?

- Franz Gleichmann

28 de marzo de 2021 a las 9:53

Siempre debes hacer este tipo de cosas en la base de datos para evitar condiciones de carrera (otros subprocesos o instancias de tu programa o incluso una aplicación diferente podrían crearlos al mismo tiempo). Puede utilizar, por ejemplo, un procedimiento almacenado. Debe derivar el código de transacción dem una columna que aumenta automáticamente su valor. Si no necesita conservar ese valor, también puede hacerlo en la consulta SELECT.

- Tim Schmelter

28/03/2021 a las 9:55



------------------------------------

Parece que su código actual quiere algo de lo que pueda extraer valores sucesivos sin insertar filas en ningún lado. No menciona qué base de datos está utilizando, pero en SQL Server este concepto es una "secuencia", consulte CREAR SECUENCIA

Sin embargo, cuando se habla de cosas como "órdenes", el enfoque más común es hacer que el Id column una "identidad" (consulte CREAR TABLA/IDENTIDAD, para que el servidor genere el ID cuando INSERTE. Puede leer el valor recién generado con cualquiera de (en orden de preferencia, antes es mejor):

la cláusula OUTPUT en INSERT SCOPE_IDENTITY() (normalmente bien, pero limitado a una fila) @@IDENTITY (muchos problemas; no lo use a menos que los demás no estén disponibles en su servidor)



------------------------------------

Puedo ver que la generación de tu ID no está relacionada con SQL. Estás intentando generarlo en C# por alguna razón, así que intenta reemplazar esto:

if (dr.Read())
{
    int code = int.Parse(dr[0].ToString()) + 1;
    transactionCode = code.ToString("000");

}
else if (Convert.IsDBNull(dr))
{
    transactionCode = ("001");
}
else
{
    transactionCode = ("001");
}

Con esto: Editado - código actualizado

    int code; //OR int code = 0;
    if (dr.Read())
    {
        code = int.Parse(dr[0].ToString()) + 1;
        transactionCode = code.ToString("000");
    }
    else if (Convert.IsDBNull(dr))
    {
        transactionCode = ("001");
    }
    else
    {
        transactionCode = ("001");
    }

Si no funciona, edite su publicación y agregue algunos datos de muestra, por favor.



------------------------------------

Apoyo las sugerencias de que utilice una columna de identidad SQL. Dicho esto, suponiendo que no controlas el esquema...

La lógica de su intento aquí es defectuosa en un par de maneras... Primero, estoy bastante seguro de que desea consultar MAX(TransactionCode) En segundo lugar, puede tener fácilmente dos clientes que realicen consultas muy cerca uno del otro, ambos leen el código de transacción máximo actual y ambos lo incrementan para obtener el mismo código nuevo. Por lo tanto, desea eliminar el incremento de su código C# y hacerlo en SQL scri.pt si es posible con algo como esto (NB, vea el comentario de @Marc Gravell a continuación)...

INSERT INTO tblOrders (TransactionCode, field1, field2...)
VALUES (CONVERT(VARCHAR(10), SELECT CONVERT(INT, MAX(TransactionCode)) + 1) FROM tblOrders, newfield1data, ...)

3

Incluso cuando se realiza en la base de datos, el enfoque MAX es una condición de carrera

- Marc Gravell

28/03/2021 a las 10:20

Tienes razón. ¿Cuál es la mejor respuesta que también evita cambiar la base de datos?¿Sí?

AlanK

28 de marzo de 2021 a las 10:37

1

La mejor respuesta, si se le da la indicación "no cambiar la base de datos", es volverse hacia quien dio esa indicación y decirle "no, estás equivocado". para obtener los resultados correctos, el único enfoque sensato es cambiar la base de datos; cualquier otro enfoque no es más que dejar una mina terrestre en el sistema”. Nunca tengas miedo de desafiar los requisitos y rechazarlos: eso es, literalmente, lo más valioso que podemos hacer, a menudo.

- Marc Gravell

28/03/2021 a las 11:39

Su guía para un futuro mejor - libreflare
Su guía para un futuro mejor - libreflare