How do I LIMIT the number of rows in a DELETE with

2019-02-21 15:16发布

I want to add a security on a sensitive table when I delete lines with an SQL request on a DB2 table.

I want to mimic the way MySQL allows you to limit the numbers of rows deleted in an SQL request.

Basically I want to do this with DB2 :

DELETE FROM table WHERE info = '1' LIMIT 1

Is there a way to do that with DB2 ?

标签: sql db2 limit
9条回答
女痞
2楼-- · 2019-02-21 16:11
delete from table where id in (select id from table where info = '1' order by id fetch first 1 rows only)
查看更多
Viruses.
3楼-- · 2019-02-21 16:14
DELETE                                      
FROM Bibl/File                             
WHERE RRN(File) =  (                        
                    SELECT min(RRN(File))   
                    FROM Bibl/File         
                    WHERE Fld1 = 'xx'     
                   )   

The RRN function is to AS400/iSeries/PowerSystem alone. In other environments there are other functions for the relative record number.

This makes it possible to erase a record of several identical even without UNIQUE key. It can also be used to update with minor changes.

works like the LIMIT but with DELETE and / or UPDATE.

It only works on SQL DB2 in other settings should be changed by RRN function to return the column number

查看更多
兄弟一词,经得起流年.
4楼-- · 2019-02-21 16:18

It really depends on your platform.

If you're using DB2 on Linux/Unix/Windows, you can just create a select that gets the rows you want, and put that as a subquery for your delete, and DB2 will be able to delete the results of your select. Like so:

DELETE FROM (
    SELECT 1
    FROM table
    WHERE info = '1'
    ORDER BY your_key_columns
    FETCH FIRST ROW ONLY
) AS A
;

If you're on DB2 for z/OS, that syntax doesn't work, unfortunately. But, you can use your primary keys to do basically the same thing (this one also works on LUW):

DELETE FROM table
WHERE (info, key2) IN (
    SELECT info, key2
    FROM table
    WHERE info = 1
    ORDER BY key2
    FETCH FIRST ROW ONLY
);

Here is an example script that demonstrates how it's used:

DECLARE GLOBAL TEMPORARY TABLE SESSION.TEST(
     ID INT
    ,RN INT
) ON COMMIT PRESERVE ROWS;

INSERT INTO SESSION.TEST 
    SELECT 1,1 FROM SYSIBM.SYSDUMMY1 UNION ALL
    SELECT 1,2 FROM SYSIBM.SYSDUMMY1 UNION ALL
    SELECT 1,3 FROM SYSIBM.SYSDUMMY1 UNION ALL
    SELECT 1,4 FROM SYSIBM.SYSDUMMY1 UNION ALL
    SELECT 1,5 FROM SYSIBM.SYSDUMMY1 UNION ALL

    SELECT 2,1 FROM SYSIBM.SYSDUMMY1 UNION ALL
    SELECT 2,2 FROM SYSIBM.SYSDUMMY1 UNION ALL
    SELECT 2,3 FROM SYSIBM.SYSDUMMY1 UNION ALL

    SELECT 3,1 FROM SYSIBM.SYSDUMMY1 UNION ALL
    SELECT 3,2 FROM SYSIBM.SYSDUMMY1 UNION ALL
    SELECT 3,3 FROM SYSIBM.SYSDUMMY1 UNION ALL

    SELECT 4,1 FROM SYSIBM.SYSDUMMY1 UNION ALL
    SELECT 4,2 FROM SYSIBM.SYSDUMMY1 UNION ALL

    SELECT 5,1 FROM SYSIBM.SYSDUMMY1 UNION ALL
    SELECT 6,1 FROM SYSIBM.SYSDUMMY1 UNION ALL
    SELECT 7,1 FROM SYSIBM.SYSDUMMY1 UNION ALL
    SELECT 8,1 FROM SYSIBM.SYSDUMMY1 UNION ALL
    SELECT 9,1 FROM SYSIBM.SYSDUMMY1 UNION ALL
    SELECT 10,1 FROM SYSIBM.SYSDUMMY1
;

SELECT * FROM SESSION.TEST ORDER BY ID, RN;

-- LUW Version
DELETE FROM (
    SELECT 1
    FROM SESSION.TEST
    WHERE ID = 1
    ORDER BY RN
    FETCH FIRST ROW ONLY
) AS A
;

--Mainframe version
DELETE FROM SESSION.TEST
WHERE (ID, RN) IN (
    SELECT ID, RN
    FROM SESSION.TEST
    WHERE ID = 1
    ORDER BY RN
    FETCH FIRST ROW ONLY
);

SELECT * FROM SESSION.TEST ORDER BY ID, RN;

DROP TABLE SESSION.TEST;
查看更多
登录 后发表回答