【问题标题】:Yield Return equivalent in SQL ServerSQL Server 中的等效收益返回
【发布时间】:2012-10-28 18:08:48
【问题描述】:

我在 SQL Server (DWH) 中写下一个视图,用例伪代码是:

-- Do some calculation and generate #Temp1
-- ... contains other selects

-- Select statement 1
SELECT * FROM Foo
JOIN #Temp1 tmp on tmp.ID = Foo.ID
WHERE Foo.Deleted = 1

-- Do some calculation and generate #Temp2
-- ... contains other selects

-- Select statement 2
SELECT * FROM Foo
JOIN #Temp2 tmp on tmp.ID = Foo.ID
WHERE Foo.Deleted = 1

视图的结果应该是:

Select Statement 1
UNION
Select Statement 2

预期的行为与 C# 中的 yield return 相同。有没有办法告诉视图哪些SELECT 语句实际上是结果的一部分,哪些不是?因为在我需要之前的小计算也包含选择。

谢谢!

【问题讨论】:

  • 一个视图由一个 single SELECT 语句组成。您实际上是指存储过程而不是视图吗?
  • 不正确,您可以在视图和存储过程中执行相同的代码。只要你使用 UNION、EXCEPT、INTERSECT 等。你可以使用多个 SELECT
  • 是的,但我的意思是在更广泛的意义上,即包含一个带有 UNION 等的 SELECT 语句。 (顺便说一句,这仍然会构成一个单个 SQL 语句。)让我感到困惑(并首先让我发表评论)是这句话:Is there a way to tell the view which SELECT statements are actually part of the result and which are not?。所以我想我会澄清这一点。
  • 好吧,正确的做法应该是正确的进入存储过程。除非出于安全考虑,最终用户具有受限的 db_reader 角色,只能访问视图。

标签: sql sql-server view yield


【解决方案1】:

C# 中的 Yield return 一次返回一行,因为它们出现在某些底层函数中。 SQL 语句中不存在这个概念。 SQl 是基于集合的,在概念上作为一个单元返回整个结果集。 (也就是说,有时查询运行缓慢,您会看到缓慢或成批返回的行。)

您可以使用TOP(在 SQL Server 中)控制返回的行数。您可以使用WHERE 语句选择要返回的特定行。但是,您不能指定有条件地从某些组件而不是其他组件返回行的UNION 语句。

你最接近的可能是这样的:

if UseTable1Only = 'Y'
    select *
    from Table1
else if UseTable2Only = 'Y'
    select *
    from Table2
else
    select *
    from table1
    union
    select *
    from table2

您可以使用动态 SQL 执行类似的操作,将语句构造为字符串然后执行。

【讨论】:

    【解决方案2】:

    我找到了更好的解决方法。它可能对其他人有帮助。它实际上是将所有计算都包含在WITH 语句中,而不是在视图核心中进行:

    WITH Temp1 (ID)
    AS
    (
        -- Do some calculation and generate #Temp1
        -- ... contains other selects
    )
    
    , Temp2 (ID)
    AS
    (
        -- Do some calculation and generate #Temp2
        -- ... contains other selects
    )
    
    -- Select statement 1
    SELECT * FROM Foo
    JOIN Temp1 tmp on tmp.ID = Foo.ID
    WHERE Foo.Deleted = 1
    
    UNION
    
    -- Select statement 2
    SELECT * FROM Foo
    JOIN Temp2 tmp on tmp.ID = Foo.ID
    WHERE Foo.Deleted = 1
    

    结果当然是所有外部SELECT 语句中的UNION

    【讨论】:

    • 顺便提一下,您提到的“WITH”语句称为公用表表达式(CTE)。一个经常让人们感到困惑的小问题是,紧接在 CTE 之前的语句必须以分号结尾(分号是 SQL 中的语句终止符。人们经常在 T-SQL 中忽略它们,因为它们是可选的 -除了紧接在需要它们的 CTE 之前的语句。)
    • @SimonTewsi 除非您的脚本实际上以 WITH 开头;)
    猜你喜欢
    • 2011-07-01
    • 2016-10-04
    • 2020-04-21
    • 2011-02-24
    • 1970-01-01
    • 1970-01-01
    • 2013-12-11
    • 2014-08-29
    • 2018-11-25
    相关资源
    最近更新 更多