SQL Server:使用一个表中的信息删除另一个行中的行
我在编写一些SQL Server脚本以从两个数据库中删除几行时遇到了一些困难。我已经看到关于该主题的其他几个问题,但似乎没有任何工作适用于这种情况。我提前为这样一个基本问题表示道歉,但这是一个无法弥补的问题。我查询了很多数据,但很少写表格。SQL Server:使用一个表中的信息删除另一个行中的行
我有两个表rollinfo
和defects
它们由
defects.roll_id = rollinfo.roll_idx
挂有一个在rollinfo
表中的列称为rollinfo.num_defects
。
如果该值大于@MAX_DEFECTS
,我想将其删除。另外我想从defects
表中删除任何相应的行。
选择这个信息很简单:
SELECT
D.ROLL_ID,
R.ROLL_IDX
FROM
VISION17SLITTER.DBO.ROLLINFO R
INNER JOIN
VISION17SLITTER.DBO.DEFECTS D ON D.ROLL_ID = R.ROLL_IDX
WHERE
R.NUM_DEFECTS > @MAX_DEFECTS
但是我不知道是否行可以从两个表中一次通过只是改变了select语句删除或者如果我需要做某种类型的删除“哪里存在”声明。
为了记录,这将是约20万行,所以如果有多种方法来做到这一点,我想知道哪个更有效。
感谢,
丹
由于需要从2个表删除,则需要有两个DELETE
报表,所以我认为最好的办法是把你需要删除的ID写入临时表中d,然后用它来驱动你的两个DELETE
声明:
-- create the temp table - you didn't mention what the datatype for these two columns is - adapt as needed
CREATE TABLE #IDsToBeDeleted (ID INT NOT NULL)
-- select those ID's you want to delete into the temp table
INSERT INTO #IDsToBeDeleted (ID)
SELECT
D.ROLL_ID
FROM
VISION17SLITTER.DBO.ROLLINFO R
INNER JOIN
VISION17SLITTER.DBO.DEFECTS D ON D.ROLL_ID = R.ROLL_IDX
WHERE
R.NUM_DEFECTS > @MAX_DEFECTS
-- based on the temp table, now delete from the two tables
-- again, from your question it isn't entirely clear which
-- is the "parent" table, and which the "child" table - so you
-- might need to change the order of deleting those rows to
-- match your situation
BEGIN TRANSACTION
BEGIN TRY
DELETE FROM VISION17SLITTER.DBO.DEFECTS
WHERE ROLL_ID IN (SELECT ID FROM #IDsToBeDeleted)
DELETE FROM VISION17SLITTER.DBO.ROLLINFO
WHERE ROLL_IDX IN (SELECT ID FROM #IDsToBeDeleted)
COMMIT TRANSACTION
END TRY
BEGIN CATCH
-- report and log the error
ROLLBACK TRANSACTION
END CATCH
marc_s,这使得很多意义我觉得我需要删除语句。我会试试这个。 – mreff555
我建议包装在一个事务中的情况后,同时从ROLLINFO删除您的第一个表已被删除,否则你可能无法出现的问题重新创建ID列表并重新运行删除。 –
@EdwardComeau:绝对 - 更新我的回应以突出这一事实 –
你试过吗?
这可能会也可能不会工作,具体取决于您的数据库。否则,在同一批次中使用两次删除(你说你想写一个脚本,所以一批是正确的事情)。在这个简单的例子,你并不需要一个事务,因为你已经知道你是用数据库交互的唯一的人:
DELETE D
FROM
VISION17SLITTER.DBO.ROLLINFO R
INNER JOIN
VISION17SLITTER.DBO.DEFECTS D
ON D.ROLL_ID = R.ROLL_IDX
WHERE R.NUM_DEFECTS > @MAX_DEFECTS;
DELETE R
FROM
VISION17SLITTER.DBO.ROLLINFO R
WHERE R.NUM_DEFECTS > @MAX_DEFECTS;
GO
如果你真的不想要一个脚本来手动启动,同时应用程序看台不过,你必须考虑并发性和实际成交价是为了:
BEGIN TRANSACTION
DELETE D
FROM
VISION17SLITTER.DBO.ROLLINFO R
INNER JOIN
VISION17SLITTER.DBO.DEFECTS D
ON D.ROLL_ID = R.ROLL_IDX
WHERE R.NUM_DEFECTS > @MAX_DEFECTS;
DELETE R
FROM
VISION17SLITTER.DBO.ROLLINFO R
WHERE R.NUM_DEFECTS > @MAX_DEFECTS;
COMMIT;
您无法从两个表中删除一个'DELETE'语句。 –
不真实的,它取决于数据库的实现,也有支持它的一些甲骨文和MySQL(InnoDB的)版本,这就是为什么我提出两种解决方案,如果第一个不工作(其中OP具有测试),那么第二次来到in。 – pid
好吧,问题被标记为[sql-server],它绝对不支持这种语法。另一方面,我没有意识到其他DBMS可能会支持它。我今天学了些新东西。谢谢。 –
使用可以使用'级联delete'外键约束,所以你只需要一次删除的缺陷,他们会从相关表中删除。 –
[从一个查询中的两个表中删除]的可能重复(http://stackoverflow.com/questions/1233451/delete-from-two-tables-in-one-query) – pid