Edit 1: added one small note regarding ANSI_WARNINGS & ARITHABORT OFF.
If you use SQL Server 2008 (I see you have questions regarding this version) you could try composable DML.
Simple solution:
INSERT Target
SELECT q.Id, q.Name, q.Type
FROM
(
DELETE Source
OUTPUT deleted.Id, deleted.Name, deleted.Type
WHERE Type = @Type --or another search condition
) q;
Complex scenario (including errors):
1.First test case demonstrates this "technique".
2.The second test demonstrates the behavior when an error is encountered during statement execution: the statement (INSERT + DELETE OUTPUT) is canceled but the batch is still executed till last statement.
3.For the third test you can see that an error can abort the "entire" batch and the statement (INSERT + DELETE OUTPUT) is, also, canceled.
The behavior regarding errors is controlled in this script using three settings: ANSI_WARNINGS, ARITHABORT and XACT_ABORT. When both settings (ANSI_WARNINGS and ARITHABORT) are OFF then this expression 1/0 will be evaluated to NULL => so, will be INSERT ... NULL.
SET NOCOUNT ON;
CREATE TABLE dbo.Source (Id INT PRIMARY KEY, Name VARCHAR(10) NOT NULL, Type TINYINT NOT NULL);
INSERT dbo.Source (Id, Name, Type) VALUES (1,'A',1), (2, 'B',1), (3, 'C',2), (4, 'D',2), (5, 'E',2);
CREATE TABLE dbo.Target (Id INT PRIMARY KEY, Name VARCHAR(10) NOT NULL, Type TINYINT /*NOT*/ NULL);
--***** Test 1 Ok *****
DECLARE @Type INT = 1;
SELECT 'Test 1 Ok' AS Description;
BEGIN TRAN;
INSERT Target
SELECT q.Id, q.Name, q.Type
FROM
(
DELETE Source
OUTPUT deleted.Id, deleted.Name, deleted.Type
WHERE Type = @Type
) q;
SELECT * FROM Target;
SELECT * FROM Source;
--It will be fine to COMMIT transaction but I will cancel to run the second and third test
ROLLBACK TRAN
SELECT 'End of Test 1 Ok' AS Description;
GO
--***** End of Test 1 *****
--***** Test 2 Err *****
--Start another batch
GO
SET ARITHABORT ON;
SET ANSI_WARNINGS ON;
SET XACT_ABORT OFF;
DECLARE @Type INT = 1;
SELECT 'Test 2 Err' AS Description, SESSIONPROPERTY('ARITHABORT') [ARITHABORT_STATUS], SESSIONPROPERTY('ANSI_WARNINGS') [ANSI_WARNINGS_STATUS];
INSERT Target
--Divide by zero => Abort statement only
SELECT q.Id, q.Name, CASE WHEN q.Id <> 2 THEN q.Type ELSE 1/0 END
FROM
(
DELETE Source
OUTPUT deleted.Id, deleted.Name, deleted.Type
WHERE Type = @Type
) q;
SELECT * FROM Target;
SELECT * FROM Source;
SELECT 'End of Test 2 Err' AS Description;
--***** End of Test 2 *****
--***** Test 3 *****
--Start another batch
GO
SET ANSI_WARNINGS OFF;
SET ARITHABORT ON;
SET XACT_ABORT OFF;
DECLARE @Type INT = 1;
SELECT 'Test 3 Err' AS Description, SESSIONPROPERTY('ARITHABORT') [ARITHABORT_STATUS], SESSIONPROPERTY('ANSI_WARNINGS') [ANSI_WARNINGS_STATUS];
INSERT Target
--Divide by zero => Abort batch
SELECT q.Id, q.Name, CASE WHEN q.Id <> 2 THEN q.Type ELSE 1/0 END
FROM
(
DELETE Source
OUTPUT deleted.Id, deleted.Name, deleted.Type
WHERE Type = @Type
) q
--This statement is not executed
SELECT * , 1 AS Statement FROM Target;
--This statement is not executed
SELECT * , 1 AS Statement FROM Source;
--This statement is not executed
SELECT 'End of Test 3 Err' AS Description
GO --Start another batch
SELECT * , 2 AS Statement FROM Target;
SELECT * , 2 AS Statement FROM Source;
--***** End of Test 3 *****
DROP TABLE dbo.Source;
DROP TABLE dbo.Target;