【问题标题】:How can I delete rows in the main table that match the ID in my temp table?如何删除主表中与临时表中的 ID 匹配的行?
【发布时间】:2014-12-13 17:42:39
【问题描述】:

下面是我的 SQL 代码。在删除部分,我在 WITH 语句中声明的对象“tblDeletes”给了我无效的对象名称,这可能是什么问题?谢谢你。

    USE [NEDB_beta]
GO
/****** Object:  StoredProcedure [dbo].[cms_cpAdminDeleteContentItemById]    Script Date: 12/13/2014 12:11:11 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:      <Author,,Name>
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- =============================================
ALTER PROCEDURE [dbo].[cms_cpAdminDeleteContentItemById] 
@ID int
AS
BEGIN
WITH    tblDeletes AS 
        (
        SELECT  *
        FROM    [NEDB_beta].[dbo].[cms_tblContent]
        WHERE   ID = @ID -- this condition defines the ultimate ancestors in your chain, change it as appropriate
        UNION ALL
        SELECT  c.*
        FROM    [NEDB_beta].[dbo].[cms_tblContent] as c
        JOIN    tblDeletes
        ON      c.intParentIdDraft = tblDeletes.ID
        )
SELECT  *
FROM    tblDeletes

DELETE FROM [NEDB_beta].[dbo].[cms_tblContent] 
WHERE ID IN 
    (SELECT ID 
     FROM tblDeletes);

END

【问题讨论】:

  • 我不确定该查询是否有意义。但是您在 tblDeletes 定义中引用了 tbldeletes。我也没有看到您从子 ID 中选择父 ID。此外,您可能根本不需要 with。但我认为你的问题的根源是你在你的定义中引用了 tblDeletes。
  • 因为您使用的是 CTE,而 CTE 仅针对一个查询定义。但是在这里您使用的是相同的 CTE。 CTE范围只能用于一个语句,不能使用两次。
  • @tlbignerd 这就是你编写递归 CTE 的方式。
  • 嗯,谢谢@Martin Smith,我以前从未见过这个。

标签: sql .net sql-server tsql


【解决方案1】:

因为您使用的是 CTE,而 CTE 仅针对一个查询定义。但是在这里您使用的是相同的 CTE。 CTE范围只能用于一个语句,不能使用两次。

删除select语句,创建CTE后,我认为不需要,因为你的主要动机是删除记录。

但如果你想使用SELECT 语句,那么要么重复 CTE 创建步骤,要么使用 Temp 表代替 CTE。

ALTER PROCEDURE [dbo].[cms_cpAdminDeleteContentItemById] 
@ID int
AS
BEGIN
WITH    tblDeletes AS 
        (
        SELECT  *
        FROM    [NEDB_beta].[dbo].[cms_tblContent]
        WHERE   ID = @ID -- this condition defines the ultimate ancestors in your chain, change it as appropriate
        UNION ALL
        SELECT  c.*
        FROM    [NEDB_beta].[dbo].[cms_tblContent] as c
        JOIN    tblDeletes
        ON      c.intParentIdDraft = tblDeletes.ID
        )

DELETE FROM [NEDB_beta].[dbo].[cms_tblContent] 
WHERE ID IN 
    (SELECT ID 
     FROM tblDeletes);

END

【讨论】:

  • 如果他们需要 Select 他们也可以OUTPUT DELETED.*
【解决方案2】:

您可以在后面的语句中使用公用表表达式。你已经用它来SELECT 了。之后它就不再“存在”了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-17
    • 2011-03-23
    • 1970-01-01
    • 2021-11-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多