标题:IN 和 INLIST() 在 where 条件中有缺陷
只看楼主
kiff
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:广州
等 级:贵宾
威 望:46
帖 子:756
专家分:2531
注 册:2013-1-30
得分:0 
以下是引用TonyDeng在2013-3-25 11:17:32的发言:

这是字符串比较的默认设置造成的,没有使用精确(set exact on或==算符)比较。对别的数据类型,不会出现这种现象,但对字符串,就会存在这种问题。
    我用set exact on 结果也是这样,查过资料,set exact on 不适用vfp的 SQL,我前天统计数据时发现这问题

[ 本帖最后由 kiff 于 2013-3-25 11:22 编辑 ]
2013-03-25 11:20
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
得分:0 
in是SQL的语法,SQL语法并不是VFP语言本身设计的,它怎么工作是这个指令体系自己的事,我从来回避用SQL指令,不知道,你说的不适用是指在in参数下。在inlist()中,就归VFP管,你测试一下inlist("02", "0201")和inlist("0201", "02")的返回结果就知道了。

授人以渔,不授人以鱼。
2013-03-25 11:25
kiff
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:广州
等 级:贵宾
威 望:46
帖 子:756
专家分:2531
注 册:2013-1-30
得分:0 
以下是引用TonyDeng在2013-3-25 11:25:42的发言:

in是SQL的语法,SQL语法并不是VFP语言本身设计的,它怎么工作是这个指令体系自己的事,我从来回避用SQL指令,不知道,你说的不适用是指在in参数下。在inlist()中,就归VFP管,你测试一下inlist("02", "0201")和inlist("0201", "02")的返回结果就知道了。
测试了,以下结果一样。
inlist(DM,"02", "0201")和inlist(DM,"0201", "02") 、DM IN ("02", "0201")、DM IN ("0201", "02")
如果是sqlserver 或 oracle ,DM IN ("02", "0201")就没这问题



[ 本帖最后由 kiff 于 2013-3-25 11:31 编辑 ]
2013-03-25 11:29
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
得分:0 
VFP执行INLIST("0201", "02")函数,转换为逻辑判断"0201"="02",在set exact off下,这个结果为真,反之为假。

授人以渔,不授人以鱼。
2013-03-25 11:33
kiff
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:广州
等 级:贵宾
威 望:46
帖 子:756
专家分:2531
注 册:2013-1-30
得分:0 
以下是引用TonyDeng在2013-3-25 11:33:05的发言:

VFP执行INLIST("0201", "02")函数,转换为逻辑判断"0201"="02",在set exact off下,这个结果为真,反之为假。
是的,在命令窗口测试,如 ?INLIST("0201", "02"),确是这结果,但用在 vfp SQL  就不一样了.
2013-03-25 11:35
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
得分:0 
INLSIT(x, v1, v1, v3)的用法是测试x是否与后面的列表v1、v2、v3有匹配,任何一个匹配都返回真。你上面的两个INLIST()其实是同一个语句,结果当然一样了。

授人以渔,不授人以鱼。
2013-03-25 11:36
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
得分:0 
我对字符串比较,从来都使用==精确比较,对INLIST(),不用于字符串。==会使执行速度减慢,但不会出错。VFP的查询和搜索会启动Rushmore优化加速,其中的手段之一就是对=使用简化比较法,当指令含有==算符时,不会启动Rushmore,所以这个时候会慢。这些细微的地方,在用于SQL时,是要注意的,毕竟VFP是用自己的方法实现SQL的结果,它并非完全与SQL Server兼容,正如各种不同厂家和平台的C/C++编译器的实现方法有差异一样。在SQL Server中,好像没有INLIST()函数,但在VFP的SQL指令中有,就说明这是厂家差异。

授人以渔,不授人以鱼。
2013-03-25 11:43
kiff
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:广州
等 级:贵宾
威 望:46
帖 子:756
专家分:2531
注 册:2013-1-30
得分:0 
现找到解决这问题的初步办法(还需大量数据验证)。
办法就是在各字符子串后加上一个空格
如 INLIST(dm,'0202 ','02 ')
或 dm in ('0202 ','02 ')
--------------------------
现在发现多加的这空格很奥妙,
select * from 表 where  dm='02 ' &&多了一个空格
select * from 表 where  dm=='02'
以上这两句是等价的

而下面的结果就非常不一样了.
select * from 表 where  dm='02' &&没加空格




[ 本帖最后由 kiff 于 2013-3-25 17:43 编辑 ]
2013-03-25 16:58
taohua300
Rank: 12Rank: 12Rank: 12
来 自:光
等 级:贵宾
威 望:14
帖 子:1636
专家分:3906
注 册:2009-3-11
得分:0 
我的做法
Set Exact On

并且比较的时候使用 ==

个性太多,无法显示
2013-03-26 09:29



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-401793-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.109211 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved