代码之家  ›  专栏  ›  技术社区  ›  Eton B.

尝试用两个表修复SQL查询

  •  0
  • Eton B.  · 技术社区  · 14 年前

    我有以下表格:

    进入

    EntryDate-日期时间

    小时

    小时-日期时间
    OutHour-日期时间

    对于Entry表中的每个注册表,Hour表上至少应该有一个(可以有多个)注册表,如下所示:

    进入
    入口ID:8

    小时
    入口ID:8

    外出时间:2010年9月9日18:21:19

    现在,这些信息存储在两个相同的数据库中,一个在本地计算机上,另一个在服务器上。我正在尝试编写一个查询,在不删除没有OutHour(null)的注册表的情况下,该查询将删除已经传递到服务器的所有信息。

    我写了以下查询:

    DELETE from [dbo].[Entry]
     WHERE [dbo].[Entry].[EntryID] IN (SELECT [EntryID] 
                                         FROM [LINKEDSERVER].[MYDATABASE].[dbo].[Entry]) 
      AND [dbo].[Entry].[EntryID] IN (SELECT [EntryID] 
                                        FROM [dbo].[Hour] 
                                       WHERE [OutHour] IS NOT NULL)
    
    DELETE from [dbo].[Hour]
     WHERE [dbo].[Hour].[InHour] IN (SELECT [InHour] 
                                       FROM [LINKEDSERVER].[MYDATABASE].[dbo].[Hour]) 
       AND [dbo].[Hour].[OutHour] IS NOT NULL 
    

    我做错什么了?感谢您的帮助。

    谢谢!

    2 回复  |  直到 14 年前
        1
  •  0
  •   DForck42    14 年前

    我的第一个建议是将两者之间的外键关系放在EntryID上。这将防止在不首先从工时表中删除所有实例的情况下从条目表中删除任何实例。

    第二,有了外键,就必须从子级到父级(也就是从层次结构的底部开始)。这意味着我要先做这个:

    delete from dbo.Hour where OutHour is not null
    delete e
    from dbo.Entry e
    left outer join dbo.Hour h
    on e.entryid=h.entryid
    where h.entryid is null
    
        2
  •  1
  •   momo    14 年前

    问题是,第二个查询只使用InHour,而没有引用EntryID。另外,第一个查询的条件彼此完全独立,如果您的工时表约束是正确的(当第二列不为null时,第一列永远不能为null),这可能不是问题,但是值得一看。

    让我把你的查询重写为连接,也许它能帮助你找出问题所在。

    DELETE E
    FROM
       dbo.Entry E
       INNER JOIN LINKEDSERVER.MYDATABASE.dbo.Entry L ON E.EntryID = L.EntryID
       INNER JOIN Hour H ON E.EntryID = H.EntryID
    WHERE
       H.OutHour IS NOT NULL
    
    DELETE H
    FROM
       dbo.Hour H
       INNER JOIN LINKEDSERVER.MYDATABASE.dbo.Hour L ON H.InHour L.InHour
    WHERE
       H.OutHour IS NOT NULL
    

    我建议您在小时表上设置级联删除外键约束,以便从条目表中删除时,子小时行都会消失。这里仍然存在一些问题,因为每个EntryID可能有许多小时行,从语义上讲,您可能会多次尝试删除链接服务器上的同一行。

    最后,如果您确实发现您的查询在链接上不必要地拉取了大量数据集(通过在远程matchine上运行queryprofiler来确定这一点,以查看提交的实际查询),那么策略性地使用CROSS-APPLY可以通过强制逐行处理来提供帮助,在链接服务器的情况下,这可能是一个错误 巨大的