按 ID 删除多行并检查这些 ID 是否不在其他表中
Deleting multiple rows by ids and checking if those ids are not in other tables
我有一个要删除的 ids
列表,但我必须检查这些 ID 是否不在其他表中 first.If 我想将这些 ID 插入到另一个列表中由列分隔。假设 @keywords
是 ids
的列表。
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( ContentKeyword
、JobKeyword
、CategoryGroup
)。有了上面的功能,这就相当简单了。只需对函数执行 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
这个怎么样?
我有一个要删除的 ids
列表,但我必须检查这些 ID 是否不在其他表中 first.If 我想将这些 ID 插入到另一个列表中由列分隔。假设 @keywords
是 ids
的列表。
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( ContentKeyword
、JobKeyword
、CategoryGroup
)。有了上面的功能,这就相当简单了。只需对函数执行 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
这个怎么样?