公用表表达式(CTE)引发的改变执行顺序同WHERE条件顺序引发的bug
以下模拟一下CTE出错
/*测试环境
Microsoft SQL Server 2008 R2 (RTM) - 10.50.1600.1 (X64) Apr 2 2010 15:48:46 Copyright (c) Microsoft Corporation Developer Edition (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1)
*/
生成表Tab数据:
--> --> (Roy)生成測試數據
if not object_id('Tab') is null
drop table Tab
Go
Create table Tab([Col1] int,[COl2] nvarchar(5))
Insert Tab
select 1,N'a,b,c' union all
select 2,N'd,e' union all
select 3,N'f'
Go
方法1:用CTE引发函数出错
if object_id('Tempdb..#Tab') is not null
drop table #Tab
select top 100 ID=Identity(int,1,1) into #Tab from syscolumns a,syscolumns b
declare @Str varchar(10)='a'
;with Cte
as
(
Select
a.Col1,COl2=substring(a.Col2,b.ID,charindex(',',a.Col2+',',b.ID)-b.ID)
from
Tab a,#Tab b
where
charindex(',',','+a.Col2,b.ID)=b.ID --也可用 substring(','+a.COl2,b.ID,1)=','
)
select Col1 from Cte where @str=COl2
/*
消息 537,级别 16,状态 3,第 8 行
传递给 LEFT 或 SUBSTRING 函数的长度参数无效。
*/
方法2:直接用语句时不会报错:
if object_id('Tempdb..#Tab') is not null
drop table #Tab
select top 100 ID=Identity(int,1,1) into #Tab from syscolumns a,syscolumns b
declare @Str varchar(10)='a'
Select
a.Col1
from
Tab a,#Tab b
where
charindex(',',','+a.Col2,b.ID)=b.ID --也可用 substring(','+a.COl2,b.ID,1)=','
and substring(a.Col2,b.ID,charindex(',',a.Col2+',',b.ID)-b.ID) =@Str
/*
Col1
1
*/
方法3:把Where条件换一下顺序也出错
if object_id('Tempdb..#Tab') is not null
drop table #Tab
select top 100 ID=Identity(int,1,1) into #Tab from syscolumns a,syscolumns b
go
declare @Str varchar(10)='a'
Select
a.Col1
from
Tab a,#Tab b
where
substring(a.Col2,b.ID,charindex(',',a.Col2+',',b.ID)-b.ID) =@Str and charindex(',',','+a.Col2,b.ID)=b.ID --也可用 substring(','+a.COl2,b.ID,1)=','
查原因从执行计划来找
if object_id('Tempdb..#Tab') is not null
drop table #Tab
select top 100 ID=Identity(int,1,1) into #Tab from syscolumns a,syscolumns b
go
SET SHOWPLAN_ALL ON;
go
--a.查看方法1执行计划
declare @Str varchar(10)='a'
;with Cte
as
(
Select
a.Col1,COl2=substring(a.Col2,b.ID,charindex(',',a.Col2+',',b.ID)-b.ID)
from
Tab a,#Tab b
where
charindex(',',','+a.Col2,b.ID)=b.ID --也可用 substring(','+a.COl2,b.ID,1)=','
)
select Col1 from Cte where @str=COl2
go
--b.查看方法2执行计划
declare @Str varchar(10)='a'
Select
a.Col1
from
Tab a,#Tab b
where
charindex(',',','+a.Col2,b.ID)=b.ID --也可用 substring(','+a.COl2,b.ID,1)=','
and substring(a.Col2,b.ID,charindex(',',a.Col2+',',b.ID)-b.ID) =@Str
go
SET SHOWPLAN_ALL off
go
方法1、方法2生成的执行计划图
方法1:可看到语句先执行条件(@str=COl2),再执行(charindex(',',','+a.Col2,b.ID)=b.ID)
公用表表达式(CTE)引发的改变执行顺序同WHERE条件顺序引发的bug的更多相关文章
- T-SQL 公用表表达式(CTE)
公用表表达式(CTE) 在编写T-SQL代码时,往往需要临时存储某些结果集.前面我们已经广泛使用和介绍了两种临时存储结果集的方法:临时表和表变量.除此之外,还可以使用公用表表达式的方法.公用表表达式( ...
- 公用表表达式(CTE)
在编写T-SQL代码时,往往需要临时存储某些结果集.前面我们已经广泛使用和介绍了两种临时存储结果集的方法:临时表和表变量.除此之外,还可以使用公用表表达式的方法.公用表表达式(Common Table ...
- SQL Server 公用表表达式(CTE)实现递归
公用表表达式简介: 公用表表达式 (CTE) 可以认为是在单个 SELECT.INSERT.UPDATE.DELETE 或 CREATE VIEW 语句的执行范围内定义的临时结果集.CTE 与派生表类 ...
- mysql8 公用表表达式CTE的使用
公用表表达式CTE就是命名的临时结果集,作用范围是当前语句. 说白点你可以理解成一个可以复用的子查询,当然跟子查询还是有点区别的,CTE可以引用其他CTE,但子查询不能引用其他子查询. 一.cte的语 ...
- SQL Server 公用表表达式(CTE)实现递归的方法
公用表表达式简介: 公用表表达式 (CTE) 可以认为是在单个 SELECT.INSERT.UPDATE.DELETE 或 CREATE VIEW 语句的执行范围内定义的临时结果集.CTE 与派生表类 ...
- SQL Server温故系列(3):SQL 子查询 & 公用表表达式 CTE
1.子查询 Subqueries 1.1.单行子查询 1.2.多行子查询 1.3.相关子查询 1.4.嵌套子查询 1.5.子查询小结及性能问题 2.公用表表达式 CTE 2.1.普通公用表表达式 2. ...
- 存储过程——公用表表达式(CTE)
目录 0. 背景说明 1. 定义及语法细节 1.1 基本定义 1.2 基本语法 1.3 多个CTE同时声明 1.4 CTE嵌套使用 2. CTE递归查询 2.1 简介 2.2 准备工作 2.3 计算每 ...
- SQL Server中公用表表达式 CTE 递归的生成帮助数据,以及递归的典型应用
本文出处:http://www.cnblogs.com/wy123/p/5960825.html 我们在做开发的时候,有时候会需要一些帮助数据,必须需要连续的数字,连续间隔的时间点,连续的季度日期等等 ...
- 公用表表达式CTE
公用表表达式CTE表面上和派生表非常相似,看起来只是语义上的区别.但和派生表比较起来,CTE具有几个优势:第一,如果须要在一个CTE中引用另一个CTE,不需要像派生表那样嵌套,相反,只要简单地在同一个 ...
- 详解公用表表达式(CTE)
简介 对于SELECT查询语句来说,通常情况下,为了使T-SQL代码更加简洁和可读,在一个查询中引用另外的结果集都是通过视图而不是子查询来进行分解的.但是,视图是作为系统对象存在数据库中,那对于结果集 ...
随机推荐
- 基于吉日嘎底层架构的Web端权限管理操作演示-用户管理
相信博客园的朋友对吉日嘎拉都不陌生,相信很多人也买了他的源码,应用于自己的项目. 但是你有没有过一个困惑? 那就是:没有一个基于网页的权限管理界面. 今天,这一切都不再是问题,我花了3年时间研究学习并 ...
- ASP.NET MVC4 传递Model到View
原文发表在:http://www.star110.com/Note/ReadArticle/60641215331146140043.html 开发环境:.NET MVC4 + EF6.0 模型: 1 ...
- csharp: Export or Import excel using NPOI
excel 2003: using System; using System.Collections.Generic; using System.ComponentModel; using Syste ...
- kfreebsd不适用于实际环境
debian搞的kfreebsd,其中有很多常用的软件包处于依赖破损的状态,个人觉得是无法用作日常开发或生产环境的. 当然,对于只使用其中几项完整可用功能的场景,基本上还是可以的. 当时看个这个东东的 ...
- MyBatis中的特殊符号[20160713]
今天中午回到工位已经是12:20多了,没有时间睡觉了,本想着还能提前开始,结果看了点新闻之后,又是12:40了,所以新闻坚决不能看,执行力. 今天主要记录一下MyBatis中的特殊符号的问题,这个问题 ...
- [小北De编程手记] : Lesson 01 - Selenium For C# 之 环境搭建
在我看来一个自动化测试平台的构建,是一种很好的了解开发语言,单元测试框架,自动化测试驱动,设计模式等等等的途径.因此,在下选择了自动化测试的这个话题来和大家分享一下本人关于软件开发和自动化测试的认识. ...
- .NET Core常用配置文件示例
.NET Core相关地址: 1.官网:https://www.microsoft.com/net 2..NET Core:http://dotnet.github.io/3.Getting Star ...
- (四)play之yabe项目【页面】
(四)play之yabe项目[页面] 博客分类: 框架@play framework 主页面 显示当前发表博客的完整内容,以及历史博客列表 Bootstrap Job 一个play job任务就是 ...
- React对话框组件实现
当下前端届最火的技术之一莫过于React + Redux + webpack的技术结合.最近公司内部也正在转react,这周主要做了个React的modal组件,接下来谈下具体实现过程. 基本的HTM ...
- .NET 面试题整理
概念类 请你说说.NET中类和结构的区别? 答:结构和类具有大体的语法,但是结构受到的限制比类要多. 结构不能申明有默认的构造函数,为结构的副本是又编译器创建和销毁的,所以不需要默认的构造函数和析构函 ...