设为首页 加入收藏

TOP

公用表表达式(CTE)引发的改变执行顺序同WHERE条件顺序引发的bug
2015-07-24 10:26:57 来源: 作者: 【 】 浏览:1
Tags:公用 表达式 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  (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生成的执行计划图 \



】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇表结构变更后出现的ERROROGG-0116.. 下一篇Websphere优化的四个方面举例

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·C语言中,“指针”用 (2025-12-26 15:20:18)
·在c语言的指针运算中 (2025-12-26 15:20:15)
·C语言-函数指针与函 (2025-12-26 15:20:12)
·求navicat for mysql (2025-12-26 13:21:33)
·有哪位大哥推荐一下m (2025-12-26 13:21:30)