从表中获取自增ID

3

我有这段代码:

string conStr = ConfigurationManager.ConnectionStrings["BackgammonGame"].ConnectionString;
            SqlConnection con = new SqlConnection(conStr);
            SqlCommand cmd = new SqlCommand();
            cmd.Connection = con;

            con.Open();
            cmd.CommandText = ("INSERT INTO Game (playerA, playerB) OUTPUT INSERTED.gameID VALUES (@playerA, @playerB)");

            cmd.Parameters.Add("@playerA", SqlDbType.NVarChar).Value = firstPlayer;
            cmd.Parameters.Add("@playerB", SqlDbType.NVarChar).Value = secondPlayer;

            cmd.ExecuteNonQuery();

            int id = (int)cmd.ExecuteScalar();
            con.Close();

当我插入这个表时,我有一个名为gameID的自动递增整数主键列,并在SQL语句中声明我想要输出gameID。我的问题是,在代码中写下这行: int id = (int)cmd.ExecuteScalar(); 插入的参数出现了两次(有相同信息的2行),但当我删除它时就没事了。
我需要这一行,以便我可以在其他表中使用此ID。
2个回答

2

使用这个命令文本并尝试

cmd.CommandText = ("INSERT INTO Game (playerA, playerB) VALUES (@playerA,@playerB); 
                     SELECT  SCOPE_IDENTITY()"); 

SCOPE IDENTITY会返回最近插入的一行的标识值,因此使用插入查询时它将返回插入行的标识字段。

编辑

您正在执行查询两次

cmd.ExecuteNonQuery(); // Avoid this
int id = (int)cmd.ExecuteScalar();// This is enough

在这两种情况下,您的查询都会被执行并导致插入两次。 ExecuteNonQuery()将执行插入查询,并返回受影响的行数。
ExecuteScalar()将返回select scope_identity()语句的结果,该语句是插入行的标识列。
以下是您的代码。
 con.Open();
 cmd.CommandText = ("INSERT INTO Game (playerA, playerB) VALUES (@playerA,@playerB); 
                     SELECT  SCOPE_IDENTITY()"); 

 cmd.Parameters.Add("@playerA", SqlDbType.NVarChar).Value = firstPlayer;
 cmd.Parameters.Add("@playerB", SqlDbType.NVarChar).Value = secondPlayer;

 int id = Convert.ToInt32(cmd.ExecuteScalar());
 con.Close();

SELECT SCOPE_IDENTITY() 给我插入的 ID?现在我在这一行上遇到了一个异常:int id = (int)cmd.ExecuteScalar(); 异常是转换不正确。 - Shimrit Revivo
SCOPE IDENTITY 返回插入行的标识值 - Nithesh Narayanan
也尝试像这样转换 Convert.ToInt32(cmd.ExecuteScalar()) - Nithesh Narayanan
它仍然插入了两行而不是一行...可能的问题是什么? - Shimrit Revivo
避免使用 cmd.ExecuteNonQuery(),只使用 cmd.ExecuteScalar() 即可。你同时调用这两个方法,所以才会出现重复插入的问题。 - Nithesh Narayanan
没错!谢谢。我怀疑那就是问题所在,只是不确定这样做是否正确,因为它只有一个参数。 - Shimrit Revivo

1
将您的命令修改为以下内容。
INSERT INTO YourTable(val1, val2, val3 ...) 
VALUES(@val1, @val2, @val3...)
SELECT SCOPE_IDENTITY()

但是我个人更喜欢编写一个存储过程,并将主键作为该存储过程的输出参数返回。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接