2010-10-28 4 views
30

Je veux faire quelque chose comme ceci:Comment supprimer plusieurs lignes avec des ID différents?

DELETE FROM table WHERE id IN (SELECT ....) 

Comment puis-je faire cela?

+0

Quelle base de données? Dans la plupart des cas, ce que vous décrivez devrait fonctionner. – Thilo

+0

Comment ne pas faire ça? Qu'est-ce qui ne fonctionne pas? Quelle base de données utilisez-vous? Oracle/MySql/SqlServer? – Fermin

+0

Clarifiez où vous obtiendrez la liste des identifiants de ..., oui il est possible de faire supprimer où id dans ... –

Répondre

80

Si vous devez sélectionner l'ID:

DELETE FROM table WHERE id IN (SELECT id FROM somewhere_else) 

Si vous les connaissez déjà (et ils ne sont pas dans les milliers):

DELETE FROM table WHERE id IN (?,?,?,?,?,?,?,?) 
+0

Si elles sont dans les milliers cela va-t-il avoir un impact sur la performance? J'essaye d'enlever quelques doublons et quelques endroits que j'ai entre deux ou trois doublons. Pour les autres entrées, je pourrais avoir quelques centaines ou milliers. – Zeliax

0

Disclaim: the following suggestion could be an overhead depending on the situation. The function is only tested with MSSQL 2008 R2 but seams be compatible to other versions

si vous Vous pouvez utiliser un function qui crée une table temporaire où vous pourrez supprimer. la sélection

comment la requête pourrait ressembler à:

-- not tested 
-- @ids will contain a varchar with your ids e.g.'9 12 27 37' 
DELETE FROM table WHERE id IN (SELECT i.number FROM iter_intlist_to_tbl(@ids)) 

ici est la fonction:

ALTER FUNCTION iter_intlist_to_tbl (@list nvarchar(MAX)) 
    RETURNS @tbl TABLE (listpos int IDENTITY(1, 1) NOT NULL, 
         number int NOT NULL) AS 

    -- funktion gefunden auf http://www.sommarskog.se/arrays-in-sql-2005.html 
    -- dient zum übergeben einer liste von elementen 

BEGIN 
    -- Deklaration der Variablen 
    DECLARE @startpos int, 
      @endpos int, 
      @textpos int, 
      @chunklen smallint, 
      @str  nvarchar(4000), 
      @tmpstr nvarchar(4000), 
      @leftover nvarchar(4000) 

    -- Startwerte festlegen 
    SET @textpos = 1 
    SET @leftover = '' 

    -- Loop 1 
    WHILE @textpos <= datalength(@list)/2 
    BEGIN 

     -- 
     SET @chunklen = 4000 - datalength(@leftover)/2 --datalength() gibt die anzahl der bytes zurück (mit Leerzeichen) 

     -- 
     SET @tmpstr = ltrim(@leftover + substring(@list, @textpos, @chunklen))--SUBSTRING (@string ,start , length) | ltrim(@string) abschneiden aller Leerzeichen am Begin des Strings 

     --hochzählen der TestPosition 
     SET @textpos = @textpos + @chunklen 

     --start position 0 setzen 
     SET @startpos = 0 

     -- end position bekommt den charindex wo ein [LEERZEICHEN] gefunden wird 
     SET @endpos = charindex(' ' COLLATE Slovenian_BIN2, @tmpstr)--charindex(searchChar,Wo,Startposition) 

     -- Loop 2 
     WHILE @endpos > 0 
     BEGIN 
      --str ist der string welcher zwischen den [LEERZEICHEN] steht 
      SET @str = substring(@tmpstr, @startpos + 1, @endpos - @startpos - 1) 

      --wenn @str nicht leer ist wird er zu int Convertiert und @tbl unter der Spalte 'number' hinzugefügt 
      IF @str <> '' 
       INSERT @tbl (number) VALUES(convert(int, @str))-- convert(Ziel-Type,Value) 

      -- start wird auf das letzte bekannte end gesetzt 
      SET @startpos = @endpos 

      -- end position bekommt den charindex wo ein [LEERZEICHEN] gefunden wird 
      SET @endpos = charindex(' ' COLLATE Slovenian_BIN2, @tmpstr, @startpos + 1) 
     END 
     -- Loop 2 

     -- dient dafür den letzten teil des strings zu selektieren 
     SET @leftover = right(@tmpstr, datalength(@tmpstr)/2 - @startpos)--right(@string,anzahl der Zeichen) bsp.: right("abcdef",3) => "def" 
    END 
    -- Loop 1 

    --wenn @leftover nach dem entfernen aller [LEERZEICHEN] nicht leer ist wird er zu int Convertiert und @tbl unter der Spalte 'number' hinzugefügt 
    IF ltrim(rtrim(@leftover)) <> '' 
     INSERT @tbl (number) VALUES(convert(int, @leftover)) 

    RETURN 
END 


    -- ############################ WICHTIG ############################ 
    -- das is ein Beispiel wie man die Funktion benutzt 
    -- 
    --CREATE PROCEDURE get_product_names_iter 
    --  @ids varchar(50) AS 
    --SELECT P.ProductName, P.ProductID 
    --FROM  Northwind.Products P 
    --JOIN  iter_intlist_to_tbl(@ids) i ON P.ProductID = i.number 
    --go 
    --EXEC get_product_names_iter '9 12 27 37' 
    -- 
    -- Funktion gefunden auf http://www.sommarskog.se/arrays-in-sql-2005.html 
    -- dient zum übergeben einer Liste von Id's 
    -- ############################ WICHTIG ############################ 
1
Delete from BA_CITY_MASTER where CITY_NAME in (select CITY_NAME from BA_CITY_MASTER group by CITY_NAME having count(CITY_NAME)>1); 
+0

Vous devez formater votre code en le sélectionnant et en appuyant sur ctrl-k. En outre, il est utile de fournir quelques explications, suggérant peut-être ce qui ne va pas dans le code de la question (s'il y a lieu). –

+0

C'est une excellente solution: 'DELETE FROM [TableName] WHERE [NomColonne] IN (SELECT [NomColonne] FROM [NomTable] GROUP BY [NomColonne] HAVING COUNT ([ColumnName])> 1);' – dakab

-4
  • Vous pouvez faire cela.

    CREER PROC [dbo]. [Sp_DELETE_MULTI_ROW]
    @CODE XML , @ ERRFLAG CHAR (1) = '0' SORTIE

AS

SET NOCOUNT ON
SET TRANSACTION NIVEAU D'ISOLATION LECTURE NON COMMANDEE

DELETE tb_SampleTest O WH CODE IN ( SELECT Item.value (' ' 'VARCHAR (20)') de @ CODE.nodes (' liste des enregistrements/ID') x AS (point) )

IF @@ ROWCOUNT = 0 SET @ ERRFLAG = 200

SET NOCOUNT OFF

  • < 'liste des enregistrements'> < 'ID'> 1 < '/ ID'> < 'ID'> 2 < '/ ID'> < '/ liste des enregistrements' >
Questions connexes