选择 SQL Server 数据库中的最后一条记录并不总是有效

Ron*_*ngu 2 c# sql sql-server

有一个声明表,当用户创建声明时,它会被插入到该表中,每个声明都应该有自己唯一的NaturalOrderID分配给它,它NaturalOrderID是由系统生成的,这是代码的第一部分,这是方法获取最大数字,这是稍后用于新的唯一数字的最后一个数字NaturalOrderID

 private int GetLastNaturalClaimNo(string finYear)
 {
        int maxNo = 0;
        string query = string.Empty;

        query = @"SELECT MAX(CAST(SubString(NaturalOrderId, 4,50) AS int)) FROM Claim
WHERE NaturalOrderId LIKE '" + finYear + "/%' AND (CAST(SubString(NaturalOrderId, 4,50) AS int) BETWEEN 10000 AND 500000) ";

        using (SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["RAC_DARAConnectionString"].ConnectionString))
        {
            SqlCommand cmd = new SqlCommand(query, conn);// ***OLD Query**
            conn.Open();

            object result = cmd.ExecuteScalar();

            // If no claim of this sort is found, then we are starting a new financial year.
            maxNo = string.IsNullOrEmpty(result.ToString()) ? 10000 : Convert.ToInt32(result);
        }

        return maxNo;
    }
Run Code Online (Sandbox Code Playgroud)

然后这个返回最大值将用于将新的声明分配给将创建的新声明,这是根据上一个方法的最大数量NaturalOrderId生成新声明的代码OrderId

public string GenerateNaturalClaimNumber(int claimId, DateTime date, string userName)
{
        // Get the financial period
        string finYear = GetFinancialYear(date);

        // Get the maximum claim inserted
        int maxClaimNo = GetLastNaturalClaimNo(finYear);

        int newClaimNo = maxClaimNo + 1;

        string naturalNo = finYear + "/" + newClaimNo.ToString();

        // Update the claim with the new number ASAP (before someone else grabs the number and creates a duplicate)
        using (SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["RAC_DARAConnectionString"].ConnectionString))
        {
            string sql = @"UPDATE Claim SET 
                    NaturalOrderId = @naturalNo, 
                    UserName = @userName
                    WHERE ClaimId = @claimId";
            //"UPDATE Claim SET NaturalOrderId = '" + naturalNo + "' WHERE ClaimId = " + claimId.ToString()
            using (SqlCommand cmd = new SqlCommand(sql, conn))
            {
                cmd.CommandType = CommandType.Text;
                cmd.Parameters.AddWithValue("@naturalNo", naturalNo);
                cmd.Parameters.AddWithValue("@userName", string.IsNullOrEmpty(userName) ? null : userName);
                cmd.Parameters.AddWithValue("@ClaimId", claimId.ToString()); // it was claimNo
                conn.Open();
                cmd.ExecuteNonQuery();
            }
        }

        return naturalNo;
    }
Run Code Online (Sandbox Code Playgroud)

我的问题是,这似乎并不总是有效,因为它有时会将相同的内容分配naturalOrderId给两个或多个不同的声明(所附几个示例的屏幕截图)

NaturalOrderID 重复项

gh9*_*gh9 5

你在你的应用程序端计算naturalOrderID,你100%应该使用identitySQL Server提供的列。可能发生的情况是您同时有多个订单进入,因此当您提取最大 ID 时,其他人会在您计算时插入。因此你的自然秩序是不同步的。

尝试使用SQL Server Identity 属性