以下模拟一下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. 【推荐】iOS集合视图的可重新排序的layout

    在实际项目中你或许会遇到在一个集合视图中移动一项到另外一个位置,那么此时我们需要对视图中的元素进行重新排序,今天推荐一个很好用的第三方类LXReorderableCollectionViewFlowL ...

  2. Spring基础——在 Spring Config 文件中基于 XML 的 Bean 的自动装配

    一.Spring IOC 容器支持自动装配 Bean,所谓自动装配是指,不需要通过 <property> 或 <constructor-arg> 为 Bean 的属性注入值的过 ...

  3. C#开发的高性能EXCEL导入、导出工具DataPie(支持MSSQL、ORACLE、ACCESS,附源码下载地址)[转]

    转自:http://www.cnblogs.com/yfl8910/archive/2012/05/19/2509194.html 作为财务数据核算人员,面对大量的业务与财务数据,借助于传统的EXCE ...

  4. [转]在SqlServer 中解析JSON数据

      在Sqlserver中可以直接处理Xml格式的数据,但因为项目需要所以要保存JSON格式的数据到Sqlserver中在博客:Consuming JSON Strings in SQL Server ...

  5. 购买SSL证书到部署网站遇到的若干问题

    作为一个菜鸟,对于SSL证书,我了解不多,只知道用了它网站更安全,所以这次使用SSL证书途中遇到了各方面的各种问题,到今天为止终于全部解决. 一.证书格式 前两天在那什么云上面买了个SSL证书,是Wo ...

  6. Array(数组)与Json String (Json字符串) 的相互转换

    1.Array转换成Json String             function jsonToString(arr) {             var s = "";     ...

  7. js限制input输入

    1.取消按钮按下时的虚线框,在input里添加属性值 hideFocus 或者 HideFocus=true <input type="submit" value=" ...

  8. (转)x11vnc配置--ubuntu14.04

    原文网址:http://www.cnblogs.com/elmaple/p/4354814.html x11vnc是连接到真实的X会话,相比vnc4server和tightvncserver自己创建不 ...

  9. (HY000): Cannot modify @@session.sql_log_bin inside a transaction

    昨天,线上发生一例(HY000): Cannot modify @@session.sql_log_bin inside a transaction代码缺少显示的start transaction控制 ...

  10. 项目、SVN clean的一些事

    1.如果你发现你的文件修改了.Tomcat也重新了,但访问的还是旧的文件,这个时候你需要clean下你的项目. Clean will discard all build problems and bu ...