SQL Server:如何删除行号

Posted

技术标签:

【中文标题】SQL Server:如何删除行号【英文标题】:SQL Server : how to delete a row number 【发布时间】:2018-04-18 11:01:35 【问题描述】:

我有一个 SQL Server 表(如上所示),我正在使用此命令在我的网站上的一个表中对其进行排序

SELECT * 
FROM [user]  
ORDER BY idNum DESC;

这个表(在我的网站上运行)包含我的数据库保存的所有信息(至少对于 [user] 表)

我有按钮可以从信息中删除一行(它获取我要删除的行号),如下图所示:

我想问的是有没有一种方法可以使用行号删除一行?(因为我从按钮单击中得到一个行号我只想删除该行)?

【问题讨论】:

不要使用“行号”或类似的东西来删除行 - 使用 主键 唯一可靠识别每一行 @marc_s 我打算给出完全相同的建议。使用 rownumber 实际上会导致删除错误的条目,因为您的表数据可能会在查看它和删除您想要的行之间发生变化。 你为什么不添加一个真正的行号,并将其用作主键。它会让你的生活更轻松...... @ppijnenburg 但是主键也可能会消失。我投票赞成通过主键删除,但这可以在某些假设下进行。 如果您尝试删除已经消失的 PK,您会收到错误消息。如果您删除特定的行号,那么行号很可能仍然存在,因为行数超过了您要删除的当前行。 【参考方案1】:

您可以在这里使用 CTE:

WITH cte AS (
    SELECT *, ROW_NUMBER() OVER (ORDER BY idNum DESC) rn
    FROM [user]
)

然后使用来自 UI 的行号删除:

DELETE
FROM cte
WHERE rn = <some value from UI>;

但许多(大多数?)UI 框架,例如Angular 能够将用户的整个元数据发送到 UI。因此,您通常只需使用直接来自 UI 中的按钮的 idNum 值即可删除。正如@marc_s 刚刚评论的那样,使用主键删除是一种安全的删除方式。

【讨论】:

技术上可行,但将您的内部 ID 暴露给浏览器并不是一个好主意。 @TheImpaler 我认为公开主键值没有任何问题。应用安全负责确保请求仅来自有效来源。 即使它来自正确的 IP,您可能不是在处理浏览器,而是在处理不同的用户代理。您最终可能会从另一个用户那里删除一行。 @TheImpaler 我不知道你开发什么样的应用程序,但是这个问题很久以前就解决了。通常,用户必须在每个请求中提供一个身份验证令牌。只允许从他拥有的行中删除,因此即使恶意用户进行黑客攻击,他仍然永远无法删除其他人的数据。【参考方案2】:

你可以使用ROW_NUMBER()

DELETE FROM USER
WHERE idnum IN (SELECT idnum from (SELECT idnum,ROW_NUMBER() OVER(ORDER BY 
idnum desc) AS rw FROM USER) res WHERE res.rw = @rw)

@rw 是你的行号

【讨论】:

【参考方案3】:

您使用row_number() 的方法完全是错误的。它不是线程安全的——可以将另一个用户添加到数据库中,从而丢弃您向用户显示的所有“行号”。天哪,用户加载页面并保持应用程序打开一周,而在用户开始删除某些内容之前,可能已经添加或删除了一堆新用户。

从根本上说,您的表格格式不正确。它没有主键,甚至没有任何唯一约束。

我强烈建议:

create table Users (
    userId int identity(1, 1) primary key,
    . . .
);

这是您应该用于删除的主键。您不需要向用户显示主键,只要您可以将其与每一行关联即可。

由于其他原因,主键很重要。通常,使用数据库是因为要存储多个表。主键是您如何将不同的表相互连接(使用外键关系)。

【讨论】:

以上是关于SQL Server:如何删除行号的主要内容,如果未能解决你的问题,请参考以下文章

如何彻底删除 sol server

如何删除大量数据 sql server2005 数据量在8千万左右??

在Sql Server、MySql、Oracle中如何删除视图;如何执行视图

SQL Server里如何删除一个数据库?

SQL Server如何显示行号

SQL Server如何显示行号