增量问题MS-SQL,C#

时间:2016-06-14 17:56:20

标签: c# asp.net sql-server webforms

我遇到ID增量问题。每次单击插入时ID都会增加1,但问题发生在ID 2时,它会插入值两次,如果ID 3,它会将值插入三次,依此类推。

我一直在尝试几种选择。一个是Max,另一个是查找最后一个插入的值,并在ID中添加一个。

如果有人能帮我解决这个问题,我将不胜感激。感谢

public partial class LoginInfo : System.Web.UI.Page
{
    static string myConnectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;

    private void GenerateID()
    {
        SqlConnection myConnection = new SqlConnection(myConnectionString);
        string myQuery1 = "Select Count(S_ID) from Student_Name";
        SqlCommand cmd = new SqlCommand(myQuery1, myConnection);
        myConnection.Open();
        int addOneS_ID_Table1 = Convert.ToInt32(cmd.ExecuteScalar());
        myConnection.Close();
        addOneS_ID_Table1++;
        lblstdID.Text = addOneS_ID_Table1.ToString();

        myConnection.Open();
        cmd.CommandText = "Select Count(P_ID) from Student_Pass";
        int addOneP_ID_Table2 = Convert.ToInt32(cmd.ExecuteScalar());
        myConnection.Close();
        addOneP_ID_Table2++;
        lblstdPass.Text = addOneP_ID_Table2.ToString();
        /*-----------------------------------------------------------------*/
        //SqlConnection myConnection = new SqlConnection(myConnectionString);

        //SqlCommand cmd = new SqlCommand("SELECT MAX(S_ID) as max_S_ID from Student_Name",myConnection);
        //cmd.CommandType = CommandType.Text;
        //myConnection.Open();
        //lblstdID.Text = Convert.ToString(cmd.ExecuteScalar());
        //cmd.CommandText = "SELECT MAX(P_ID) as max_P_ID FROM Student_Pass";
        //lblstdPass.Text = Convert.ToString(cmd.ExecuteScalar());
        //myConnection.Close();
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        if(!IsPostBack)
        {
            GenerateID();
        }
    }

    protected void btnInsert_Click(object sender, EventArgs e)
    {
        SqlConnection myConnection = new SqlConnection(myConnectionString);

        string myQuery = "Insert into Student_Name(S_ID,STUDENT_NAME) VALUES" + "(@S_ID,@STUDENT_NAME)";

        SqlCommand cmd = new SqlCommand(myQuery,myConnection);

        cmd.Parameters.Add("@S_ID", SqlDbType.Int).Value = lblstdID.Text;
        cmd.Parameters.Add("@STUDENT_NAME", SqlDbType.VarChar).Value = txtstdName.Text;

        if(myConnection.State == ConnectionState.Closed)
        {
            myConnection.Open();
        }

        cmd.ExecuteNonQuery();
        cmd.Parameters.Clear();

        //Second Table

        cmd.CommandText = "Insert into Student_Pass(P_ID,PASSWORD) VALUES" + "(@P_ID,@PASSWORD)";
        cmd.CommandType = CommandType.Text;

        cmd.Parameters.Add("@P_ID", SqlDbType.Int).Value = lblstdPass.Text;
        cmd.Parameters.Add("@PASSWORD", SqlDbType.VarChar).Value = txtStdPass.Text;

        cmd.ExecuteNonQuery();
        cmd.Parameters.Clear();
        myConnection.Close();
        GenerateID();
        lblResult.Text = "Successfully Saved";
        GridView1.DataBind();
    }
}

2 个答案:

答案 0 :(得分:0)

问题在于您的查询,因为您获得了COUNT(S_ID),这将使您获得记录的数量并不一定会给出确切的ID号。您应该尝试使用MAX(S_ID)ORDER BY条款

Select MAX(S_ID) from Student_Name 

(OR)

Select TOP 1 S_ID from Student_Name ORDER BY S_ID DESC; 

但建议您实际上应该使用SQL Server @@IDENTITYSCOPE_IDENTITY()来获取最后插入的记录ID(假设S_IDIDENTITY列)

答案 1 :(得分:0)

强烈建议不要使用maxtop来确定要使用的“下一个”标识符,这仅仅是因为与之相关的成本。

然而,使用maxtop还有一些其他陷阱,特别是如果有可能使用nolock(这是一个完整的其他对话)。我已经看到很多Web应用程序使用max并且已被证明是性能杀手。

Rahul是对的,@@identityscope_identity是不错的选择。但是,我认为这需要使用SQL Server 2012中引入的本机SQL Server sequence。这是应用程序开发人员一直在等待的东西,微软最终交付了它。

使用@@identityscope_identity的问题在于,您实际上必须先将行写入某个表,然后才能考虑做某事。

这使得它比它可能需要的更昂贵和更麻烦。在使用sequence的情况下,您可以发出新的序列号然后决定做什么,一旦您决定做什么,您仍然保证您是唯一一个具有该序列号的人。< / p>

你会创建一个这样的序列。您也应该查看documentation

create sequence dbo.StudentIdSeq
    as int -- this can be any integer type
    start with 1 -- you can start with any valid number in the int, even negative
    increment by 1;
go

然后你通过这样做发出新的序列号......

select next value for StudentIdSeq;

使用可以从C#调用的输出参数创建存储过程可能仍然很好(这就是我要做的)。事实上,如果你有一堆序列,你可能想要更进一步,并创建一个光滑的存储过程,它将根据调用者请求的类型获得一个新的序列。