且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

选择 SQL 表中的最后一行

更新时间:2023-02-05 09:50:43

使用自动增量字段...我想将刚刚添加的最后一个字段与其他内容连接起来.

using an auto increment field ... and i want to get the last one just added to join it with something else.

这里的关键是刚刚添加".如果您有一堆不同的用户同时访问数据库,我认为您不希望用户 A 检索用户 B 创建的记录.这意味着您可能想要使用 scope_identity() 函数来获取该 id,而不是立即再次在表上运行查询.

The key here is "just added". If you have a bunch of different users hit the db at the same time, I don't think you want user A to retrieve the record created by user B. That means you probably want to use the scope_identity() function to get that id rather than running a query on the table again right away.

根据上下文,您可能还需要 @@identity(将包括触发器)或 ident_current('questions')(仅限于特定表,但不是具体范围).但是 scope_identity() 几乎总是适合使用的.

Depending on the context you might also need @@identity (would include triggers) or ident_current('questions') (limited to a specific table, but not the specific scope). But scope_identity() is almost always the right one to use.

这是一个例子:

DECLARE @NewOrderID int

INSERT INTO TABLE [Orders] (CustomerID) VALUES (1234)

SELECT @NewOrderID=scope_identity()

INSERT INTO TABLE [OrderLines] (OrderID, ProductID, Quantity) 
    SELECT @NewOrderID, ProductID, Quantity
    FROM [ShoppingCart]
    WHERE CustomerID=1234 AND SessionKey=4321

根据您发布的代码,您可以执行以下操作:


Based on the code you posted, you can do something like this:

// don't list the ID column: it should be an identity column that sql server will handle for you
const string QUERY = "INSERT INTO Questions (Question, Answer, CategoryID, Permission) " 
                   + "VALUES (@Question, @Answer, @CategoryID, @Permission);"
                   + "SELECT scope_identity();"; 

int NewQuestionID;
using (var cmd = new SqlCommand(QUERY, conn)) 
{ 
    cmd.Parameters.AddWithValue("@Question", question); 
    cmd.Parameters.AddWithValue("@Answer", answer); 
    cmd.Parameters.AddWithValue("@CategoryID", lastEdited);
    cmd.Parameters.AddWithValue("@Permission", categoryID);
    NewQuestionID = (int)cmd.ExecuteScalar(); 
}

在此处查看我对另一个问题的回答:
获取新的 SQL 记录 ID

See my answer to another question here:
get new SQL record ID

现在的问题是您可能希望后续的 sql 语句在同一个事务中.您可以使用客户端代码执行此操作,但我发现将其全部保存在服务器上会更简洁.您可以通过构建一个很长的 sql 字符串来实现,但此时我倾向于使用存储过程.

The problem now is that you'll likely want subsequent sql statements to be in the same transaction. You could do this with client code, but I find keeping it all on the server to be cleaner. You could do that by building a very long sql string, but I tend to prefer a stored procedure at this point.

我也不喜欢 .AddWithValue() 方法 —我更喜欢明确定义参数类型 —但我们可以改天再说.

I'm also not a fan of the .AddWithValue() method — I prefer explicitly defining the parameter types — but we can leave that for another day.

最后,现在有点晚了,但我想强调的是,尝试将所有这些都保留在数据库中确实更好.在一个 sql 命令中运行多个语句是可以的,并且您希望减少需要对数据库进行的往返次数以及需要在数据库和应用程序之间来回传递的数据量.它还可以更轻松地正确处理事务并在需要的地方保持原子性.

Finally, it's kind of late now, but I want to emphasize that it's really better to try to keep this all on the db. It's okay to run multiple statements in one sql command, and you want to reduce the number of round trips you need to make to the db and the amount of data you need to pass back and forth between the db and your app. It also makes it easier to get the transactions right and keep things atomic where they need to be.