Tsql 删除子记录,但仅删除没有子记录的父记录。Sql Server 2008
不知道您能否帮我做一个简单的SQL查询 我已经包括了一个简单的脚本,用一些非常小的数据创建2个表和01 SP。有什么建议吗?谢谢 我有两张桌子 顾客 顾客 SQL查询应: 基于CustomerStoreID从CustomerItem表中删除所有项。 也删除客户,但仅当客户不再有子女时才删除 创建表和一些数据的脚本:Tsql 删除子记录,但仅删除没有子记录的父记录。Sql Server 2008,tsql,sql-server-2008,Tsql,Sql Server 2008,不知道您能否帮我做一个简单的SQL查询 我已经包括了一个简单的脚本,用一些非常小的数据创建2个表和01 SP。有什么建议吗?谢谢 我有两张桌子 顾客 顾客 SQL查询应: 基于CustomerStoreID从CustomerItem表中删除所有项。 也删除客户,但仅当客户不再有子女时才删除 创建表和一些数据的脚本: BEGIN TRANSACTION; IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo
BEGIN TRANSACTION;
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Customer]') AND type in (N'U'))
DROP TABLE [dbo].[Customer]
GO
SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Customer]
([CustomerID] [int] NOT NULL,
[Name] [nvarchar](50) NOT NULL,
[Surname] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_Customer]
PRIMARY KEY CLUSTERED ([CustomerID] ASC)
) ON [PRIMARY]
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[CustomerItem]') AND type in (N'U'))
DROP TABLE [dbo].[CustomerItem]
GO
SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[CustomerItem]
([CustomerItemID] [int] NOT NULL,
[CustomerID] [int] NOT NULL,
[CustomerStoreID] [int] NOT NULL,
[CustomerItemDescription] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_CustomerItem]
PRIMARY KEY CLUSTERED([CustomerItemID] ASC)
) ON [PRIMARY]
GO
INSERT INTO [dbo].[Customer]([CustomerID], [Name], [Surname])
SELECT 1, N'John ', N'Smith' UNION ALL
SELECT 2, N'Mark', N'Bloggs' UNION ALL
SELECT 3, N'Richard', N'Lay'
INSERT INTO [dbo].[CustomerItem]([CustomerItemID], [CustomerID], [CustomerStoreID], [CustomerItemDescription])
SELECT 1, 1, 1, N'BookOne' UNION ALL
SELECT 2, 1, 1, N'BookTwo' UNION ALL
SELECT 3, 1, 2, N'BookThree'UNION ALL
SELECT 4, 1, 2, N'BookFour' UNION ALL
SELECT 5, 2, 2, N'BookFive'UNION ALL
SELECT 6, 2, 2, N'BookSix' UNION ALL
SELECT 7, 3, 3, N'BookSeven' UNION ALL
SELECT 8, 3, 3, N'BookEight'
GO
IF EXISTS (SELECT * FROM DBO.SYSOBJECTS WHERE id = OBJECT_ID(N'[dbo].[DeleteCustomerAndItemsByStoreId]') AND OBJECTPROPERTY(id, N'IsProcedure') = 1)
DROP PROCEDURE [dbo].[DeleteCustomerAndItemsByStoreId]
GO
CREATE PROCEDURE DeleteCustomerAndItemsByStoreId
@CustomerStoreID INT
/*
Delete all customerItems based on @CustomerStoreID
Delete the customer itself when he not longer has customerItems
*/
AS
DELETE FROM CustomerItem
WHERE CustomerStoreID = @CustomerStoreID
---Loop through the customer table and Delete Customer if no longer has children
--???
COMMIT
基本上,在处理/删除最后一个客户项时,也会删除该客户
存储过程将只有一个参数@CustomerStoreID
delete Customer
where not exists (select 1
from CustomerItem
where Customer.CustomerID = CustomerItem.CustomerID)
试试这个
delete Customer
where not exists (select 1
from CustomerItem
where Customer.CustomerID = CustomerItem.CustomerID)
基本上,您的存储过程应该如下所示:
CREATE PROCEDURE DeleteCustomerAndItemsByStoreId
@CustomerStoreID INT
AS
DECLARE @CustomerIDs TABLE(CustomerID INT)
-- do the first delete and output the deleted CustomerID's into a table variable
DELETE CustomerItem
OUTPUT DELETED.CustomerID INTO @CustomerIDs(CustomerID)
WHERE CustomerStoreID = @CustomerStoreID
-- delete from the Customer table when no CustomerItems exist anymore for that CustomerID
DELETE dbo.Customer
OUTPUT DELETED.CustomerID
FROM @CustomerIDs c
WHERE
dbo.Customer.CustomerID = c.CustomerID
AND NOT EXISTS(SELECT * FROM dbo.CustomerItem WHERE CustomerID = c.CustomerID)
这应该执行两步删除-首先删除定义的CustomerStoreID的所有CustomerItem行,然后从受第一次删除影响的客户集中删除那些没有更多CustomerItem条目的客户
更新:当我运行此命令时:
SELECT * FROM customer
EXEC DeleteCustomerAndItemsByStoreId @CustomerStoreID = 2
SELECT * FROM customer
我得到:
CustomerID Name Surname
1 John Smith
2 Mark Bloggs
3 Richard Lay
CustomerID -- that from the "OUTPUT Deleted.CustomerID"
2
CustomerID Name Surname
1 John Smith
3 Richard Lay
2号客户不见了-这与您的脚本、数据有关基本上,您的存储过程应该如下所示:
CREATE PROCEDURE DeleteCustomerAndItemsByStoreId
@CustomerStoreID INT
AS
DECLARE @CustomerIDs TABLE(CustomerID INT)
-- do the first delete and output the deleted CustomerID's into a table variable
DELETE CustomerItem
OUTPUT DELETED.CustomerID INTO @CustomerIDs(CustomerID)
WHERE CustomerStoreID = @CustomerStoreID
-- delete from the Customer table when no CustomerItems exist anymore for that CustomerID
DELETE dbo.Customer
OUTPUT DELETED.CustomerID
FROM @CustomerIDs c
WHERE
dbo.Customer.CustomerID = c.CustomerID
AND NOT EXISTS(SELECT * FROM dbo.CustomerItem WHERE CustomerID = c.CustomerID)
delete c
from [Customer] as c
left join [CustomerItem] as ci
on ci.[CustomerID] = c.[CustomerID]
where ci.[CustomerID] is null;
这应该执行两步删除-首先删除定义的CustomerStoreID的所有CustomerItem行,然后从受第一次删除影响的客户集中删除那些没有更多CustomerItem条目的客户
更新:当我运行此命令时:
SELECT * FROM customer
EXEC DeleteCustomerAndItemsByStoreId @CustomerStoreID = 2
SELECT * FROM customer
我得到:
CustomerID Name Surname
1 John Smith
2 Mark Bloggs
3 Richard Lay
CustomerID -- that from the "OUTPUT Deleted.CustomerID"
2
CustomerID Name Surname
1 John Smith
3 Richard Lay
2号客户不见了-这是您的脚本,您的数据作为旁注:如果您发现这些检查过于复杂。。。。。对于一个表,请尝试以下操作:如果存在,请从sys.tables中选择*,其中name='Customer',对于一个过程,请使用sys.procedures目录视图-这比一般的sys.objects要容易得多,然后必须指定要查找的对象类型,我认为….作为旁注:如果发现这些检查,您会做得过于复杂。。。。。对于一个表,请尝试以下操作:如果存在,请从sys.tables中选择*,其中name='Customer',对于一个过程,请使用sys.procedures目录视图-比一般的sys.objects更易于使用,然后必须指定要查找的对象类型,我认为….是customerstoreID 1,有两个客户。这就是为什么我像以前一样创建了我的答案。非常感谢您的回复和时间。我已尝试了您的查询,但如果执行EXEC[dbo].[DeleteCustomerAndItemSystoreId]@CustomerStoreID=2,则该查询似乎不起作用。我仍然在表中看到customerID=2的客户,因为它应该显示出来。基本上,我需要删除属于customerID的所有customerItems,当customerID没有更多的子项时,也将其删除。是的customerstoreID 1,有2个客户。这就是为什么我像以前一样创建了我的答案。非常感谢您的回复和时间。我已尝试了您的查询,但如果执行EXEC[dbo].[DeleteCustomerAndItemSystoreId]@CustomerStoreID=2,则该查询似乎不起作用。我仍然在表中看到customerID=2的客户,因为它应该显示出来。基本上,我需要删除属于customerID的所有customerItems,并且当customerID没有更多的子项时,也删除这些子项。我假设他的意思是删除customerItems中受第一次删除影响的客户-不是所有客户,而是所有客户他们,你的代码当然工作得很好!他需要一个反向级联删除:-我假设他的意思是删除那些受CustomerItems中第一次删除影响的客户-不是所有客户,但对于所有客户,您的代码肯定工作得很好!他需要一个反向级联删除:-谢谢你的工作!!感谢大家的投入和时间。如果没有,很抱歉clear@Beth,我无法编辑您的答案,因为我的编辑只有一个字符。。但是您应该编写select distinct c.CustomerID,否则您可能会得到错误的模棱两可的列名谢谢您的工作!!感谢大家的投入和时间。如果没有,很抱歉clear@Beth,我无法编辑您的答案,因为我的编辑只有一个字符。。但是您应该编写selectdistinct c.CustomerID,否则您可能会得到错误的不明确的列名
delete c
from [Customer] as c
left join [CustomerItem] as ci
on ci.[CustomerID] = c.[CustomerID]
where ci.[CustomerID] is null;