Sql server 不使用datetime或ID删除SQL Server中的最新条目

Sql server 不使用datetime或ID删除SQL Server中的最新条目,sql-server,delete-row,Sql Server,Delete Row,我有一个基本的SQL Server删除脚本: Delete from tableX where colA = ? and colB = ?; 在表x中,我没有任何列指示顺序ID或时间戳;只需varchar。我想删除插入的最新条目,但我无权访问插入脚本中的行号顶部不是选项,因为它是随机的。此外,这个特定的表没有主键,这不是设计不佳的问题。我有什么办法可以做到这一点吗?我记得mysql能够调用类似于max(row\u number)的东西,以及类似于limit one的东西 SQL Server

我有一个基本的SQL Server删除脚本:

Delete from tableX 
where colA = ? and colB = ?;

表x
中,我没有任何列指示顺序ID或时间戳;只需
varchar
。我想删除插入的最新条目,但我无权访问插入脚本中的行号<代码>顶部不是选项,因为它是随机的。此外,这个特定的表没有主键,这不是设计不佳的问题。我有什么办法可以做到这一点吗?我记得mysql能够调用类似于
max(row\u number)
的东西,以及类似于limit one的东西

SQL Server中也存在
行编号
,但它必须与
OVER(order\u by\u子句)
一起使用。所以在你的情况下,这是不可能的,除非你想出另一个排序算法

编辑:(来自MSDN的George的例子……恐怕他的公司有防火墙规则阻止MSDN)

SQL代码

USE AdventureWorks2012; 
GO
SELECT ROW_NUMBER() OVER(ORDER BY SalesYTD DESC) AS Row, 
    FirstName, LastName, ROUND(SalesYTD,2,1) AS "Sales YTD" 
FROM Sales.vSalesPerson
WHERE TerritoryName IS NOT NULL AND SalesYTD <> 0;

返回行的子集

USE AdventureWorks2012;
GO
WITH OrderedOrders AS
(
    SELECT SalesOrderID, OrderDate,
    ROW_NUMBER() OVER (ORDER BY OrderDate) AS RowNumber
    FROM Sales.SalesOrderHeader 
) 
SELECT SalesOrderID, OrderDate, RowNumber  
FROM OrderedOrders 
WHERE RowNumber BETWEEN 50 AND 60;

将行数()与分区一起使用

USE AdventureWorks2012;
GO
SELECT FirstName, LastName, TerritoryName, ROUND(SalesYTD,2,1),
ROW_NUMBER() OVER(PARTITION BY TerritoryName ORDER BY SalesYTD DESC) AS Row
FROM Sales.vSalesPerson
WHERE TerritoryName IS NOT NULL AND SalesYTD <> 0
ORDER BY TerritoryName;

SQL Server中也存在
行编号
,但它必须与
OVER(order\u by\u子句)
一起使用。所以在你的情况下,这是不可能的,除非你想出另一个排序算法

编辑:(来自MSDN的George的例子……恐怕他的公司有防火墙规则阻止MSDN)

SQL代码

USE AdventureWorks2012; 
GO
SELECT ROW_NUMBER() OVER(ORDER BY SalesYTD DESC) AS Row, 
    FirstName, LastName, ROUND(SalesYTD,2,1) AS "Sales YTD" 
FROM Sales.vSalesPerson
WHERE TerritoryName IS NOT NULL AND SalesYTD <> 0;

返回行的子集

USE AdventureWorks2012;
GO
WITH OrderedOrders AS
(
    SELECT SalesOrderID, OrderDate,
    ROW_NUMBER() OVER (ORDER BY OrderDate) AS RowNumber
    FROM Sales.SalesOrderHeader 
) 
SELECT SalesOrderID, OrderDate, RowNumber  
FROM OrderedOrders 
WHERE RowNumber BETWEEN 50 AND 60;

将行数()与分区一起使用

USE AdventureWorks2012;
GO
SELECT FirstName, LastName, TerritoryName, ROUND(SalesYTD,2,1),
ROW_NUMBER() OVER(PARTITION BY TerritoryName ORDER BY SalesYTD DESC) AS Row
FROM Sales.vSalesPerson
WHERE TerritoryName IS NOT NULL AND SalesYTD <> 0
ORDER BY TerritoryName;

您当前的表格设计不允许您确定最新的条目。您没有可排序的字段来指示最后添加的记录

您需要重新设计或从审计表中提取这些信息。如果您有一个没有审计表的数据库,您可能需要找到一个工具来读取事务日志,这将是一个非常耗时和昂贵的过程。或者,如果您知道要删除的记录被添加的日期,您可以使用发生此情况之前的备份来查找添加的记录。请注意,您可能正在查看在此日期之后更改的记录,您希望保留这些记录


如果您需要定期执行此操作,而不是一次性修复一些错误数据,那么您需要正确地设计数据库,使其包含标识字段和日期更新字段(通过触发器维护)或审核表。(在我看来,任何包含贵公司所依赖信息的数据库都不应该没有审计表,这是您不应该允许ORM设计数据库的众多原因之一,但我离题了。)如果您需要知道订单记录是添加到表中的,作为开发人员,您有责任创建该结构。数据库只存储为tehm设计的要存储的内容,如果您没有在中进行设计,那么它将不容易使用,或者根本不可用。

您当前的表设计不允许您确定最新的条目。您没有可排序的字段来指示最后添加的记录

您需要重新设计或从审计表中提取这些信息。如果您有一个没有审计表的数据库,您可能需要找到一个工具来读取事务日志,这将是一个非常耗时和昂贵的过程。或者,如果您知道要删除的记录被添加的日期,您可以使用发生此情况之前的备份来查找添加的记录。请注意,您可能正在查看在此日期之后更改的记录,您希望保留这些记录

如果您需要定期执行此操作,而不是一次性修复一些错误数据,那么您需要正确地设计数据库,使其包含标识字段和日期更新字段(通过触发器维护)或审核表。(在我看来,任何包含贵公司所依赖信息的数据库都不应该没有审计表,这是您不应该允许ORM设计数据库的众多原因之一,但我离题了。)如果您需要知道订单记录是添加到表中的,作为开发人员,您有责任创建该结构。数据库只存储为tehm设计的要存储的内容,如果您没有在中进行设计,那么它就不容易获得,或者根本不可用

如果
(colA+“+”+colB)
不可能重复尝试此方法

 declare @delColumn nvarchar(250)

    set @delColumn = (select top 1   DeleteColumn from (
    select (colA +'_'+ colB)  as DeleteColumn ,
          ROW_NUMBER() OVER(ORDER BY colA DESC) as Id from tableX  
    )b
    order by Id desc
    )

delete  from tableX where  (colA +'_'+ colB) =@delColumn
如果
(colA+''.+colB)
不能重复,请尝试此操作

 declare @delColumn nvarchar(250)

    set @delColumn = (select top 1   DeleteColumn from (
    select (colA +'_'+ colB)  as DeleteColumn ,
          ROW_NUMBER() OVER(ORDER BY colA DESC) as Id from tableX  
    )b
    order by Id desc
    )

delete  from tableX where  (colA +'_'+ colB) =@delColumn

要使其工作,您必须有一列可以用来确定顺序。听起来您没有办法确定“最新”行。你被困在这里是因为设计不支持这一点。任何依赖于行排序的操作都必须有一个排序列。这很奇怪,我最近看到这个问题被问了很多次,但在谷歌结果中找不到。也许是老年退休金计划删除了他们。@SeanLange和Zoff Dino,谢谢你的评论。我理解这些限制条件,并已在上文中对其进行了描述。然而,我仍在尝试我的运气,看看是否有一个可能的解决办法。没有解决办法。当没有定义“何时”时,您试图识别行。如果你没有这些信息,你就没有能力这样做。为了使这项工作正常进行,你必须有一列可以用来确定顺序。听起来您没有办法确定“最新”行。你被困在这里是因为设计不支持这一点。任何依赖于行排序的操作都必须有一个排序列。这很奇怪,我最近看到这个问题被问了很多次,但在谷歌结果中找不到。也许是老年退休金计划删除了他们。@SeanLange和Zoff Dino,谢谢你的评论。我理解这些限制条件,并已在上文中对其进行了描述。然而,我仍在尝试我的运气,看看是否有一个可能的解决办法。没有解决办法。当没有定义“何时”时,您试图识别行。如果你没有这些信息,你就没有能力这么做。谢谢。这不是“糟糕”的设计问题