Phi*_*ipp 3 sql-server common-table-expression
I had an issue today with CTEs running on SQL Server 2016, at the moment I worked around it using table variables, however I am not sure if the behavior is wrong or I am reading the documentation wrong.
When you run this query:
with cte(id) as
(
select NEWID() as id
)
select * from cte
union all
select * from cte
Run Code Online (Sandbox Code Playgroud)
I would expect two times the same guid, however there are 2 different ones. According to the documentation (https://learn.microsoft.com/en-us/sql/t-sql/queries/with-common-table-expression-transact-sql?view=sql-server-ver15) it "Specifies a temporary named result set". However, the above example shows, that it is not a result set, but executed whenever used.
This thread is not about finding a different approach, but much rather checking if there is something wrong with it.
公用表表达式不是临时表、物化视图或缓存结果集。它们只是表达式,并且可以多次求值(这意味着对于像 之类的函数NEWID(),每次求值表达式时都会得到一个新值)。我在这篇文章的“当心糖”部分谈到了这一点:
即使在非常简单的情况下,您也可以看到访问表一次但被引用多次的 CTE 最终会多次评估 CTE(从而访问基础表)。
并在这里解决类似的问题:
马丁史密斯在这里有一个富有洞察力和彻底的答案:
我确实理解许多人对 CTE 的工作原理做出假设,并且我很欣赏缓存 CTE 所提供的价值。这不是它们今天的工作方式,但您可以对此反馈项目或此反馈项目进行投票,以塑造未来的功能。遗憾的是,新的反馈系统并不是很受欢迎,而受欢迎程度推动了工作,因此只有少数反馈项目拥有超过少数的选票。我认为社区在处理 Connect 的方式之后曾经愚弄过我一次。
您还可以要求他们在官方文档中添加说明- 但通常文档不会列出某个功能无法执行的所有操作。一个常见的例子是,“为什么文档没有明确说明没有不保证按某种特定顺序输出?” 或者,更抽象地说,“为什么我的汽车的用户手册没有告诉我汽车不能飞?”SELECT * FROM tableORDER BY
同时,如果您希望NEWID()每次引用它来自的位置时都有相同的值,则应该使用#temp 表、@table 变量或本地@variable。在您的示例中,更改可能很简单:
declare @newid uniqueidentifier = NEWID();
with cte(id) as
(
select @newid as id
)
select * from cte
union all
select * from cte
Run Code Online (Sandbox Code Playgroud)
示例:db<>fiddle
| 归档时间: |
|
| 查看次数: |
1463 次 |
| 最近记录: |