以下模拟一下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生成的执行计划图

 
 
注意看以上第4行的运算,再查第3行执行顺序
方法1:可看到语句先执行条件(@str=COl2),再执行(charindex(',',','+a.Col2,b.ID)=b.ID)
方法2:可看到语句先执行条件(charindex(',',','+a.Col2,b.ID)=b.ID),再执行(substring(a.Col2,b.ID,charindex(',',a.Col2+',',b.ID)-b.ID) =@Str)
 
方法3同方法1一样原因,条件的顺序也会引发执行出错
 

公用表表达式(CTE)引发的改变执行顺序同WHERE条件顺序引发的bug的更多相关文章

  1. T-SQL 公用表表达式(CTE)

    公用表表达式(CTE) 在编写T-SQL代码时,往往需要临时存储某些结果集.前面我们已经广泛使用和介绍了两种临时存储结果集的方法:临时表和表变量.除此之外,还可以使用公用表表达式的方法.公用表表达式( ...

  2. 公用表表达式(CTE)

    在编写T-SQL代码时,往往需要临时存储某些结果集.前面我们已经广泛使用和介绍了两种临时存储结果集的方法:临时表和表变量.除此之外,还可以使用公用表表达式的方法.公用表表达式(Common Table ...

  3. SQL Server 公用表表达式(CTE)实现递归

    公用表表达式简介: 公用表表达式 (CTE) 可以认为是在单个 SELECT.INSERT.UPDATE.DELETE 或 CREATE VIEW 语句的执行范围内定义的临时结果集.CTE 与派生表类 ...

  4. mysql8 公用表表达式CTE的使用

    公用表表达式CTE就是命名的临时结果集,作用范围是当前语句. 说白点你可以理解成一个可以复用的子查询,当然跟子查询还是有点区别的,CTE可以引用其他CTE,但子查询不能引用其他子查询. 一.cte的语 ...

  5. SQL Server 公用表表达式(CTE)实现递归的方法

    公用表表达式简介: 公用表表达式 (CTE) 可以认为是在单个 SELECT.INSERT.UPDATE.DELETE 或 CREATE VIEW 语句的执行范围内定义的临时结果集.CTE 与派生表类 ...

  6. SQL Server温故系列(3):SQL 子查询 & 公用表表达式 CTE

    1.子查询 Subqueries 1.1.单行子查询 1.2.多行子查询 1.3.相关子查询 1.4.嵌套子查询 1.5.子查询小结及性能问题 2.公用表表达式 CTE 2.1.普通公用表表达式 2. ...

  7. 存储过程——公用表表达式(CTE)

    目录 0. 背景说明 1. 定义及语法细节 1.1 基本定义 1.2 基本语法 1.3 多个CTE同时声明 1.4 CTE嵌套使用 2. CTE递归查询 2.1 简介 2.2 准备工作 2.3 计算每 ...

  8. SQL Server中公用表表达式 CTE 递归的生成帮助数据,以及递归的典型应用

    本文出处:http://www.cnblogs.com/wy123/p/5960825.html 我们在做开发的时候,有时候会需要一些帮助数据,必须需要连续的数字,连续间隔的时间点,连续的季度日期等等 ...

  9. 公用表表达式CTE

    公用表表达式CTE表面上和派生表非常相似,看起来只是语义上的区别.但和派生表比较起来,CTE具有几个优势:第一,如果须要在一个CTE中引用另一个CTE,不需要像派生表那样嵌套,相反,只要简单地在同一个 ...

  10. 详解公用表表达式(CTE)

    简介 对于SELECT查询语句来说,通常情况下,为了使T-SQL代码更加简洁和可读,在一个查询中引用另外的结果集都是通过视图而不是子查询来进行分解的.但是,视图是作为系统对象存在数据库中,那对于结果集 ...

随机推荐

  1. [ASP.NET]分析MVC5源码,并实现一个ASP.MVC

    本节内容不是MVC入门教程,主要讲MVC原理,实现一个和ASP.NET MVC类似基本原理的项目. MVC原理是依赖于ASP.NET管道事件基础之上的.对于这块,可阅读上节内容 [ASP.NET]谈谈 ...

  2. [Solution] 简单数字识别之Tesseract

    图像识别涉及的理论:傅里叶变换,图形形态学,滤波,矩阵变换等等. Tesseract的出现为了解决在没有这些复杂的理论基础,快速识别图像的框架. 准备: 1.样本图像学习,预处理 (平均每1个元素出现 ...

  3. PHP--正则表达式和样式匹配--小记

    正则表达式: Regular expression PHP 支持两种风格的函数: POSIX 风格的,有些低版本软件支持,目前高版本的有些已经废弃不用了,比如 zend studio 的较新版本. p ...

  4. MVC增删查改,从数据库到后台,到前端,整个复习一下

    就当是记笔记吧,这里,就不讲什么版式了,首先上数据库脚本,这个是我这次练习用到的数据库脚本: USE [DB_USERS] GO /****** Object: Table [dbo].[Studen ...

  5. C#设计模式——迭代器模式(Iterator Pattern)

    一.概述在软件开发过程中,我们可能会希望在不暴露一个集合对象内部结构的同时,可以让外部代码透明地访问其中包含的元素.迭代器模式可以解决这一问题.二.迭代器模式迭代器模式提供一种方法顺序访问一个集合对象 ...

  6. 【C#】1.2 控制台应用程序学习要点

    分类:C#.VS2015 创建日期:2016-06-14 教材:十二五国家级规划教材<C#程序设计及应用教程>(第3版) 一.要点概述 <C#程序设计及应用教程>(第3版)的第 ...

  7. YEdit

    YEdit YEdit is a YAML editor for Eclipse. See the wiki for more details Installation Use the Eclipse ...

  8. AC自动机(1)

    Description Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀).    ...

  9. HttpClient总结一之基本使用

    最近工作中是做了一个handoop的hdfs系统的文件浏览器的功能,是利用webhdfs提供的rest api来访问hdfs来与hdfs进行交互的,其中大量使用HttpClient,之前一直很忙,没什 ...

  10. HTML5的新特性

    HTML5 中的一些有趣的新特性: 用于绘画的 canvas 元素 用于媒介回放的 video 和 audio 元素 对本地离线存储的更好的支持 新的特殊内容元素,比如 article.footer. ...