2009-06-30 7 views
5

Je souhaite ajouter une sécurité sur une table sensible lorsque je supprime des lignes avec une requête SQL sur une table DB2. Je veux imiter la façon dont MySQL vous permet de limiter le nombre de lignes supprimées dans une requête SQL.Comment limiter le nombre de lignes dans un DELETE avec DB2?

Fondamentalement, je veux le faire avec DB2:

DELETE FROM table WHERE info = '1' LIMIT 1 

Est-il possible de le faire avec DB2?

Répondre

7
delete from table where id in (select id from table where info = '1' order by id fetch first 1 rows only) 
+0

Merci, mais j'ai un schéma bizarre dans lequel je n'ai pas un seul identifiant pour une ligne. J'identifie les lignes avec une clé primaire composée de 2 colonnes. – kevin

+0

qu'en est-il de l'utilisation de row_number() à la place? c'est-à-dire où row_number() dans (select row_number (... – Konstantinos

+0

Konstantinos, il devrait être «aller chercher seulement 1 lignes seulement». Les mots utilisés doivent être des lignes et non des lignes même si vous allez chercher une seule ligne :) –

-3
DELETE FROM table 
WHERE info = '1' 
FETCH FIRST 1 ROWS ONLY 
+0

Malheureusement cela ne fonctionne pas pour moi. – kevin

0

Comment est cette requête?

0

Sur IBMi DB2:

DELETE FROM table WHERE RRN(table) in 
(SELECT RRN(table) FROM table WHERE col1 = '1' AND col2 = '2' FETCH FIRST 5 ROWS ONLY) 
+0

Si vous êtes sur db2 et sur un IBMi ne pouvez-vous pas utiliser DFU pour accéder à l'enregistrement? –

0
MERGE INTO XYZ A<BR> 
USING (<BR> 
SELECT RID_BIT(B) CHAVE<BR> 
FROM XYZ B<BR> 
FETCH FIRST 100000 ROWS ONLY) B<BR> 
ON RID_BIT(A) = B.CHAVE<BR> 
WHEN MATCHED THEN DELETE; 
-1

Il suffit de sélectionner une déclaration, et mettre l'instruction à l'intérieur de la requête de suppression:

delete from (
select from table WHERE info = '1' order by id fetch first 25000 rows only 
) 
1

Si votre clé primaire a plusieurs valeurs, ou vous avez juste besoin de plusieurs valeurs comme condition, ceci est la requête qui fonctionne:

DELETE FROM TABLE 
WHERE (COLUMN1, COLUMN2) IN (
    SELECT COLUMN1, COLUMN2 FROM TABLE 
    WHERE SOME_COLUMN='THIS' 
    AND SOME_OTHER_COLUMN LIKE 'THAT%' 
    FETCH FIRST 10 ROWS ONLY) 
-1
DELETE          
FROM Bibl/File        
WHERE RRN(File) = (      
        SELECT min(RRN(File)) 
        FROM Bibl/File   
        WHERE Fld1 = 'xx'  
        ) 

La fonction RRN est de AS400/iSeries/PowerSystem seul. Dans d'autres environnements, il existe d'autres fonctions pour le numéro d'enregistrement relatif.

Ceci permet d'effacer un enregistrement de plusieurs identiques même sans clé UNIQUE. Il peut également être utilisé pour mettre à jour avec des modifications mineures.

fonctionne comme LIMIT mais avec DELETE et/ou UPDATE.

Il ne fonctionne que sur SQL DB2 dans d'autres paramètres doivent être modifiés par fonction RRN pour retourner le numéro de colonne

+1

Stackoverflow comprend seulement l'anglais! –

+0

Paresh: FRANÇAIS: J'ai mis bilingue pour atteindre le plus grand nombre de personnes. Je pense que ce qui est important n'est pas la langue ou la couleur de peau mais le message qui aide à résoudre les problèmes. ESPAÑOL: Il est en train de bilingues pour que le maire de la ville soit le numero de personas. Creo que lo importante no es idioma o la couleur de piel sino le mensaje que ayuda un résolveur los problemas –

0

Cela dépend vraiment de votre plate-forme. Si vous utilisez DB2 sous Linux/Unix/Windows, vous pouvez simplement créer un select qui récupère les lignes souhaitées, et le mettre comme sous-requête pour votre suppression, et DB2 pourra supprimer les résultats de votre sélection. Comme si:

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

Si vous êtes sur DB2 pour z/OS, cette syntaxe ne fonctionne pas, malheureusement. Mais, vous pouvez utiliser vos clés primaires pour faire essentiellement la même chose (celui-ci fonctionne aussi sur LUW):

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

Voici un exemple de script qui montre comment il est utilisé:

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;