按 ID 删除多行并检查这些 ID 是否不在其他表中

Deleting multiple rows by ids and checking if those ids are not in other tables

我有一个要删除的 ids 列表,但我必须检查这些 ID 是否不在其他表中 first.If 我想将这些 ID 插入到另一个列表中由列分隔。假设 @keywordsids 的列表。

SELECT Replace(item,'''','') AS KeywordId 
FROM   Splitdelimiterstring(@keywords,',')IF NOT EXISTS 
( 
       SELECT KeywordId 
       FROM   ContentKeyword 
       WHERE  KeywordId = ?? 
       UNION 
       SELECT KeywordId 
       FROM   JobKeyword 
       WHERE  KeywordId = ?? 
       UNION 
       SELECT KeywordId 
       FROM   CategoryGroup 
       WHERE  KeywordId= ?? ) 
BEGIN 
  DELETE 
  FROM   Keywords 
  WHERE  KeywordId =??
END
  ELSE ??

您需要做的第一件事是编写一个可以将字符串拆分为 table 的 UDF。这是我的版本。

CREATE  FUNCTION fn_Split(@Text varchar(MAX), @Delimiter varchar(20) = ',')
RETURNS @Strings TABLE
(   
  Position int IDENTITY PRIMARY KEY,
  Value varchar(MAX)  
)
AS
BEGIN

DECLARE @Index int = -1

WHILE (LEN(@Text) > 0)
  BEGIN 
    SET @Index = CHARINDEX(@Delimiter , @Text) 

    IF (@Index = 0) AND (LEN(@Text) > 0) 
      BEGIN  
        INSERT INTO @Strings VALUES (@Text)
          BREAK 
      END 

    IF (@Index > 1) 
      BEGIN  
        INSERT INTO @Strings VALUES (LEFT(@Text, @Index - 1))  
        SET @Text = RIGHT(@Text, (LEN(@Text) - @Index)) 
      END 
    ELSE
      SET @Text = RIGHT(@Text, (LEN(@Text) - @Index))

    END
  RETURN
END

下一步是编写一个 select 语句,其中 select 仅包含您的字符串中那些 存在于您的任一表格中的 ID( ContentKeywordJobKeywordCategoryGroup)。有了上面的功能,这就相当简单了。只需对函数执行 LEFT JOIN 并检查加入的 table 的 ID 是否为空:

select s.Value from dbo.fn_Split('1,2,3,4,5', ',') s
  left outer join ContentKeyword CK on CK.KeywordId = s.Value
  left outer join JobKeyword     JK on JK.KeywordId = s.Value
  left outer join CategoryGroup  JG on JG.KeywordId = s.Value
where 
  (1 = 1)
  and CK.KeywordId is null 
  and JK.KeywordId Is null 
  and JG.KeywordId is null

编辑

这是我的完整测试脚本:

if exists (select * from INFORMATION_SCHEMA.ROUTINES where ROUTINE_NAME = 'fn_Split' )
  drop function [dbo].[fn_Split]
go
CREATE  FUNCTION fn_Split(@Text varchar(MAX), @Delimiter varchar(20) = ',')
RETURNS @Strings TABLE
(   
  Position int IDENTITY PRIMARY KEY,
  Value varchar(MAX)  
)
AS
BEGIN

DECLARE @Index int = -1

WHILE (LEN(@Text) > 0)
  BEGIN 
    SET @Index = CHARINDEX(@Delimiter , @Text) 

    IF (@Index = 0) AND (LEN(@Text) > 0) 
      BEGIN  
        INSERT INTO @Strings VALUES (@Text)
          BREAK 
      END 

    IF (@Index > 1) 
      BEGIN  
        INSERT INTO @Strings VALUES (LEFT(@Text, @Index - 1))  
        SET @Text = RIGHT(@Text, (LEN(@Text) - @Index)) 
      END 
    ELSE
      SET @Text = RIGHT(@Text, (LEN(@Text) - @Index))      
    END
  RETURN
END
go

if exists (select * from INFORMATION_SCHEMA.TABLES where TABLE_NAME = 'ContentKeyword')
  drop table ContentKeyword;
go
Create Table ContentKeyword  
(
    [KeywordId] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
    [Name] [nvarchar](500) NOT NULL
)
go

if exists (select * from INFORMATION_SCHEMA.TABLES where TABLE_NAME = 'ContentKeyword')
  drop table JobKeyword;
go
Create Table JobKeyword 
(
    [KeywordId] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
    [Name] [nvarchar](500) NOT NULL
)
go
if exists (select * from INFORMATION_SCHEMA.TABLES where TABLE_NAME = 'ContentKeyword')
  drop table CategoryGroup;
go
Create Table CategoryGroup 
(
    [KeywordId] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
    [Name] [nvarchar](500) NOT NULL
)
go
  --Insert dummy data

  insert into CategoryGroup(Name)  values('First value')
go

select S.Value from dbo.fn_Split('1,2,3,4,5', ',') S
  left outer join ContentKeyword CK on CK.KeywordId = s.Value
  left outer join JobKeyword     JK on JK.KeywordId = s.Value
  left outer join CategoryGroup  JG on JG.KeywordId = s.Value
where 
  (1 = 1)
  and CK.KeywordId is null 
  and JK.KeywordId Is null 
  and JG.KeywordId is null
declare @temptable as table(
Id int
);
Insert into @temptable values(//ids)

Delete from Keyword
where Id not in (
Select KeywordId from JobKeyword 
where KeywordId in (select Id from @temptable)
union 
Select KeywordId from ContentKeyword
where KeywordId in 
(Select Id from @temptable)
union 
Select KeywordId from CategoryGroup 
where KeywordId in 
(Select Id from @temptable)
)


Select Keyword from Keyword where Id 
in( 
Select Id from @temptable
where Id not in 
(
Select KeywordId from JobKeyword 
where KeywordId in (select Id from @temptable)
union 
Select KeywordId from ContentKeyword
where KeywordId in 
(Select Id from @temptable)
union 
Select KeywordId from CategoryGroup 
where KeywordId in 
(Select Id from @temptable) 
) 
) for xml auto 

这个怎么样?