选择SQL表中的最后一行

Ahm*_*rid 6 sql sql-server

是否可以返回MS SQL Server中表的最后一行.我正在为ID使用自动增量字段,我想要添加最后一个用于加入其他内容的字段.任何的想法?

这是代码:

const string QUERY = @"INSERT INTO Questions (ID, Question, Answer, CategoryID, Permission) " 
                   + @"VALUES (@ID, @Question, @Answer, @CategoryID, @Permission) "; 

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);
    cmd.ExecuteNonQuery(); 
}
Run Code Online (Sandbox Code Playgroud)

n8w*_*wrl 24

不安全 - 可能会同时进行多个插入,而您获得的最后一行可能不属于您.最好使用SCOPE_IDENTITY()来获取为事务分配的最后一个密钥.


Joe*_*orn 19

使用自动增量字段...我希望得到最后一个添加到其他东西.

这里的关键是" 刚添加 ".如果你有一堆不同的用户同时点击数据库,我认为你不希望用户A检索用户B创建的记录.这意味着你可能想要使用该scope_identity()函数获取该id而不是运行立刻再次对桌子进行查询.

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


这是一个例子:

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
Run Code Online (Sandbox Code Playgroud)

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

// 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(); 
}
Run Code Online (Sandbox Code Playgroud)

请在此处查看我对其他问题的回答:
获取新的SQL记录ID

现在的问题是你可能希望后续的sql语句在同一个事务中.您可以使用客户端代码执行此操作,但我发现在服务器上保持更清晰.你可以通过构建一个非常长的sql字符串来做到这一点,但我倾向于在这一点上更喜欢存储过程.

我也不是该.AddWithValue()方法的粉丝- 我更喜欢明确定义参数类型 - 但我们可以将其留在另一天.

最后,现在已经很晚了,但我想强调的是,尝试将这一切保留在db上真的更好.在一个sql命令中运行多个语句是可以的,并且您希望减少需要对数据库进行的往返次数以及在数据库和应用程序之间来回传递所需的数据量.它还使得更容易获得正确的交易并将事物保持在需要的位置.


Sta*_* R. 10

使用

  • scope_identity()返回此会话和此范围中生成的最后一个标识值
  • ident_current()返回在任何会话和任何范围内为特定表生成的最后一个标识值

    选择ident_current('yourTableName')

将返回由其他会话创建的最后一个标识.

大多数情况下,您应该在插入语句之后立即使用scope_identity().

--insert statement
SET @id = CAST(SCOPE_IDENTITY() AS INT)
Run Code Online (Sandbox Code Playgroud)