在SQL Server 2000中,如何删除没有主键的表中的指定行?
假设我们有一个表,其中包含一些数据。
IF OBJECT_ID('dbo.table1') IS NOT NULL
BEGIN
DROP TABLE dbo.table1;
END
CREATE TABLE table1 ( DATA INT );
---------------------------------------------------------------------
-- Generating testing data
---------------------------------------------------------------------
INSERT INTO dbo.table1(data)
SELECT 100
UNION ALL
SELECT 200
UNION ALL
SELECT NULL
UNION ALL
SELECT 400
UNION ALL
SELECT 400
UNION ALL
SELECT 500
UNION ALL
SELECT NULL;
如何删除表中的第2、5、6条记录?该顺序由以下查询定义。
SELECT data
FROM dbo.table1
ORDER BY data DESC;
请注意,这是在SQL Server 2000环境中。
谢谢。
Let's say we have a table with some data in it.
IF OBJECT_ID('dbo.table1') IS NOT NULL
BEGIN
DROP TABLE dbo.table1;
END
CREATE TABLE table1 ( DATA INT );
---------------------------------------------------------------------
-- Generating testing data
---------------------------------------------------------------------
INSERT INTO dbo.table1(data)
SELECT 100
UNION ALL
SELECT 200
UNION ALL
SELECT NULL
UNION ALL
SELECT 400
UNION ALL
SELECT 400
UNION ALL
SELECT 500
UNION ALL
SELECT NULL;
How to delete the 2nd, 5th, 6th records in the table? The order is defined by the following query.
SELECT data
FROM dbo.table1
ORDER BY data DESC;
Note, this is in SQL Server 2000 environment.
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
简而言之,您需要表中的某些内容来指示顺序。当没有任何东西强制顺序时,“第二行”是不合逻辑的。然而,一个可能的解决方案可能是(玩具示例=>玩具解决方案):
显然,这种类型的解决方案不能保证完全按照您想要的方式工作,但这个概念是您所能得到的最好的。本质上,您将行填充到带有标识列的表中,并使用它来标识要删除的行。删除行需要清空原始表并仅使用所需的行重新填充。如果没有某种唯一的密钥,就没有干净的方法来处理这个问题。
In short, you need something in the table to indicate sequence. The "2nd row" is a non-sequitur when there is nothing that enforces sequence. However, a possible solution might be (toy example => toy solution):
Obviously, this type of solution is not guaranteed to work exactly as you want but the concept is the best you will get. In essence, you stuff your rows into a table with an identity column and use that to identify the rows to remove. Removing the rows entails emptying the original table and re-populating with only the rows you want. Without a unique key of some kind, there just is no clean way of handling this problem.
您可能知道,您可以在更高版本中使用
row_number
非常直接地执行此操作。即使没有它,也可以使用未记录的
%%LOCKRES%%
函数来区分 2 个相同的行,但我认为这在 SQL Server 2000 中不可用。
在 SQL 集中没有顺序,但游标有顺序,因此您可以使用如下所示的内容。注意:我期望能够使用
DELETE ... WHERE CURRENT OF
但这依赖于 PK,因此删除行的代码并不像我希望的那么简单。如果要删除的数据是重复的,则不能保证它将删除与
CURRENT OF
相同的行。然而,在这种情况下,关联行的排序无论如何都是任意的,因此无论删除哪一行都可以同样在游标排序中给出该行号。As you are probably aware you can do this in later versions using
row_number
very straightforwardly.Even without that it is possible to use the undocumented
%%LOCKRES%%
function to differentiate between 2 identical rowsI don't think that's available in SQL Server 2000 though.
In SQL Sets don't have order but cursors do so you could use something like the below. NB: I was expecting to be able to use
DELETE ... WHERE CURRENT OF
but that relies on a PK so the code to delete a row is not as simple as I was hoping for.In the event that the data to be deleted is a duplicate then there is no guarantee that it will delete the same row as
CURRENT OF
would have. However in this eventuality the ordering of the tied rows is arbitrary anyway so whichever row is deleted could equally well have been given that row number in the cursor ordering.要对一组行执行任何操作(例如删除它们),您需要知道标识这些行的内容。
因此,您必须提出确定要删除的行的标准。
提供一个玩具示例(如上面的示例)并不是特别有用。
To perform any action on a set of rows (such as deleting them), you need to know what identifies those rows.
So, you have to come up with criteria that identifies the rows you want to delete.
Providing a toy example, like the one above, is not particularly useful.
您提前计划,如果您预计这是可能的,您可以添加代理键列或类似的列。
一般来说,您要确保不会创建没有 PK 的表。
这就像问“假设我在过马路之前没有向两个方向看,然后我就走到了一辆公共汽车前面”。
You plan ahead and if you anticipate this is possible you add a surrogate key column or some such.
In general you make sure you don't create tables without PK's.
It's like asking "Say I don't look both directions before crossing the road and I step in front of a bus."