簡體   English   中英

SQL Server:使用一個表中的信息刪除另一個表中的行

[英]SQL Server : using information from one table to delete rows in another

我在編寫一些SQL Server腳本以從兩個數據庫中刪除幾行時遇到一些困難。 我在該主題上還看到了很多其他問題,但是在這種情況下似乎沒有任何效果。 對於此類基本問題,我事先表示歉意,但這是一個無法解決的查詢。 我查詢很多數據,但很少寫入表。

我有兩個表rollinfodefects ,它們通過鏈接

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語句即可刪除即可立即從兩個表中刪除行,或者我是否需要執行某種類型的“ where exist”語句。

記錄下來,這大約是20萬行,因此,如果有多種方法可以做到這一點,我想知道哪種效率更高。

謝謝,

由於您需要從兩個表中DELETE ,因此您將需要有兩個DELETE語句,所以我認為最好的方法是將需要刪除的ID寫入臨時表中,然后使用該ID驅動兩個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

你有嘗試過嗎?

根據您的數據庫,這可能行不通

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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM