我在编写一些SQL Server脚本以从两个数据库中删除几行时遇到一些困难。我已经看到了很多关于这个主题的其他问题,但似乎没有什么对这个场景有用。我提前为这样一个基本问题道歉,但这是一个不能搞砸的问题。我查询了很多数据,但我很少写表格。
我有两个表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
表中删除任何相应的行。
选择此信息很简单:
{{1}}
但是我不确定是否可以通过将select语句更改为删除来一次从两个表中删除行,或者我是否需要执行某些类型的"其中存在"言。
对于记录,这将是大约200k行,所以如果有多种方法可以做到这一点,我想知道哪个更有效。
谢谢,
丹
答案 0 :(得分:3)
由于您需要从两个表中删除,因此您需要有两个DELETE
语句,因此我认为最好的方法就是写下这些ID&#39}需要删除到临时表中,然后使用它来驱动两个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
答案 1 :(得分:0)
你试过这个吗?
根据您的数据库,这可能有效,也可能无效。
DELETE D, R
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 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;