2012-07-27 39 views
0

我有一个任意的值列表,我想用T-SQL在多个表中删除记录。我想在未来使用不同的值列表重用脚本。这仅仅是为了调试目的(我只是想清除记录,以便它们可以用新版本的软件重新导入),所以它不需要很漂亮。如何从多个表中删除基于任意值的数组?

到目前为止,我有:

DECLARE @RequestIDList table(Request_ID nvarchar(50) NOT NULL) 
INSERT INTO @RequestIDList (Request_ID) VALUES 
('00987172'), 
('01013218'), 
('01027886'), 
('01029552'), 
('01031476'), 
('01032882'), 
('01033085'), 
('01034446'), 
('01039261') 
DELETE FROM Request WHERE Request_ID IN (SELECT Request_ID FROM @RequestIDList) 
DELETE FROM RequestTest WHERE Request_ID IN (SELECT Request_ID FROM @RequestIDList) 

看来工作,但有没有更好的办法?我似乎无法弄清楚如何直接在IN子句中使用变量(例如“WHERE Request_ID IN @RequestIDList”)。

回答

1

首先,你需要建立一个分析输入

CREATE FUNCTION inputParser (@list nvarchar(MAX)) 
RETURNS @tbl TABLE (number int NOT NULL) AS 
BEGIN 
DECLARE @pos  int, 
    @nextpos int, 
    @valuelen int 

SELECT @pos = 0, @nextpos = 1 

WHILE @nextpos > 0 
BEGIN 
SELECT @nextpos = charindex(',', @list, @pos + 1) 
SELECT @valuelen = CASE WHEN @nextpos > 0 
         THEN @nextpos 
         ELSE len(@list) + 1 
       END - @pos - 1 
INSERT @tbl (number) 
    VALUES (convert(int, substring(@list, @pos + 1, @valuelen))) 
SELECT @pos = @nextpos 
END 
RETURN 
END 

然后使用该功能在SP

CREATE PROCEDURE usp_delete 
@RequestIDList varchar(50) 
AS 
Begin 
DELETE FROM Request as req inner join 
inputParser (@RequestIDList) i on req.Request_ID = i.number 
End 

EXEC usp_delete '1, 2, 3, 4' 

对于furthur细节的功能,请看看this文章。它解释不同的充根据不同的SQL Server版本。对于SQL Server 2008中,它使用TVP这进一步简化了输入解析器

2

快速脚本上的方法:这种类型的问题

SET NOCOUNT ON 

-- Temp table so it can be joined against in dynamic SQL 
IF OBJECT_ID('tempdb..#RequestIDList') IS NOT NULL 
    DROP TABLE #RequestIDList 
GO 

CREATE TABLE #RequestIDList (Request_ID nvarchar(50) NOT NULL) 
INSERT INTO #RequestIDList (Request_ID) VALUES 
('00987172'),('01013218'),('01027886'),('01029552'), 
('01031476'),('01032882'),('01033085'),('01034446'), 
('01039261') 

DECLARE @TableList TABLE (TableName NVARCHAR(128) NOT NULL) 
INSERT @TableList VALUES 
('Request'), 
('RequestTest') 

DECLARE 
    @sqlcmd VARCHAR(4000), 
    @table VARCHAR(128) 

-- Loop through the tables in your delete list 
DECLARE c CURSOR LOCAL FORWARD_ONLY STATIC READ_ONLY FOR 
SELECT TableName 
FROM @TableList 
ORDER BY TableName 

OPEN c 
FETCH NEXT FROM c INTO @table 
WHILE @@FETCH_STATUS = 0 
BEGIN 

    -- Assuming all tables in schema dbo 
    -- Assuming all tables have column Request_ID 
    SET @sqlcmd = 'DELETE FROM t FROM ' + QUOTENAME(@table) 
       + ' t JOIN #RequestIDList r ON r.Request_ID = t.Request_ID' 

    -- PRINT @sqlcmd 
    EXEC (@sqlcmd) 
    FETCH NEXT FROM c INTO @table 
END 

CLOSE c 
DEALLOCATE c 

-- Clean up 
DROP TABLE #RequestIDList 
+0

尼斯通用模板。谢谢 – 2018-01-30 14:50:55