How do I delete multiple rows with different IDs?

SqlSql Delete

Sql Problem Overview


I want to do something like this:

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

How can I do that?

Sql Solutions


Solution 1 - Sql

If you have to select the 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 (?,?,?,?,?,?,?,?)

Solution 2 - Sql

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

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

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

Solution 3 - Sql

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

Solution 4 - Sql

  • You can make this.

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

AS

SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

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

SET NOCOUNT OFF

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionave4496View Question on Stackoverflow
Solution 1 - SqlThiloView Answer on Stackoverflow
Solution 2 - SqlWiiMaxxView Answer on Stackoverflow
Solution 3 - SqlrahulnikhareView Answer on Stackoverflow
Solution 4 - SqlThienPhucView Answer on Stackoverflow