如何删除具有不同ID的多个行?

时间:2021-10-11 02:27:08

I want to do something like this:

我想做这样的事情:

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

How can I do that?

我怎样才能做到这一点?

4 个解决方案

#1


82  

If you have to select the id:

如果你必须选择id:

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

If you already know them (and they are not in the thousands):

如果你已经了解它们(并且它们不是成千上万):

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

#2


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);

#3


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

免责声明:根据具体情况,以下建议可能是开销。该功能仅使用MSSQL 2008 R2进行测试,但接缝与其他版本兼容

if you wane do this with many Id's you may could use a function which creates a temp table where you will be able to DELETE FROM the selection

如果你用许多Id做了这个,你可以使用一个创建临时表的函数,你可以从选择中删除

how the query could look like:

查询的外观如下:

-- 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))

here is the function:

这是功能:

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 ############################

#4


-4  

  • You can make this.

    你可以做到这一点。

    CREATE PROC [dbo].[sp_DELETE_MULTI_ROW]
    @CODE XML ,@ERRFLAG CHAR(1) = '0' OUTPUT

    CREATE PROC [dbo]。[sp_DELETE_MULTI_ROW] @CODE XML,@ ERRFLAG CHAR(1)='0'OUTPUT

AS

SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

设置交易隔离级别设置NOCOUNT读取不满意

DELETE tb_SampleTest WHERE CODE IN( SELECT Item.value('.', 'VARCHAR(20)') FROM @CODE.nodes('RecordList/ID') AS x(Item) )

DELETE tb_SampleTest WHERE CODE IN(SELECT Item.value('。','VARCHAR(20)')FROM @ CODE.nodes('RecordList / ID')AS x(Item))

IF @@ROWCOUNT = 0 SET @ERRFLAG = 200

IF @@ ROWCOUNT = 0 SET @ERRFLAG = 200

SET NOCOUNT OFF

设置NOCOUNT OFF

  • <'RecordList'><'ID'>1<'/ID'><'ID'>2<'/ID'><'/RecordList'>
  • < 'RecordList'> < 'ID'> 1 < '/ ID'> < 'ID'> 2 < '/ ID'> < '/ RecordList'>

#1


82  

If you have to select the id:

如果你必须选择id:

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

If you already know them (and they are not in the thousands):

如果你已经了解它们(并且它们不是成千上万):

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

#2


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);

#3


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

免责声明:根据具体情况,以下建议可能是开销。该功能仅使用MSSQL 2008 R2进行测试,但接缝与其他版本兼容

if you wane do this with many Id's you may could use a function which creates a temp table where you will be able to DELETE FROM the selection

如果你用许多Id做了这个,你可以使用一个创建临时表的函数,你可以从选择中删除

how the query could look like:

查询的外观如下:

-- 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))

here is the function:

这是功能:

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 ############################

#4


-4  

  • You can make this.

    你可以做到这一点。

    CREATE PROC [dbo].[sp_DELETE_MULTI_ROW]
    @CODE XML ,@ERRFLAG CHAR(1) = '0' OUTPUT

    CREATE PROC [dbo]。[sp_DELETE_MULTI_ROW] @CODE XML,@ ERRFLAG CHAR(1)='0'OUTPUT

AS

SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

设置交易隔离级别设置NOCOUNT读取不满意

DELETE tb_SampleTest WHERE CODE IN( SELECT Item.value('.', 'VARCHAR(20)') FROM @CODE.nodes('RecordList/ID') AS x(Item) )

DELETE tb_SampleTest WHERE CODE IN(SELECT Item.value('。','VARCHAR(20)')FROM @ CODE.nodes('RecordList / ID')AS x(Item))

IF @@ROWCOUNT = 0 SET @ERRFLAG = 200

IF @@ ROWCOUNT = 0 SET @ERRFLAG = 200

SET NOCOUNT OFF

设置NOCOUNT OFF

  • <'RecordList'><'ID'>1<'/ID'><'ID'>2<'/ID'><'/RecordList'>
  • < 'RecordList'> < 'ID'> 1 < '/ ID'> < 'ID'> 2 < '/ ID'> < '/ RecordList'>