Sql server 不使用datetime或ID删除SQL Server中的最新条目
我有一个基本的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
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,谢谢你的评论。我理解这些限制条件,并已在上文中对其进行了描述。然而,我仍在尝试我的运气,看看是否有一个可能的解决办法。没有解决办法。当没有定义“何时”时,您试图识别行。如果你没有这些信息,你就没有能力这么做。谢谢。这不是“糟糕”的设计问题