我目前正在开发一个工具来帮助我的用户将他们的sql代码移植到sql-Server 2005.为此,我将sql解析为语法树,分析它需要注意的构造,修改它并将其转换回T – sql.
在我想要支持的事情上,其他RDBMS的“bools is values too”语义.例如,MS-Access允许我从A中选择A.x和A.y作为r,这在T-sql中是不可能的,因为:
>列不能具有布尔类型(列值不能和’)
>在期望表达式的地方不能使用逻辑谓词.
因此,我的转换例程将上述语句转换为:
select case when (A.x<>0) and (A.y<>0) then -1 when not((A.x<>0) and (A.y<>0)) then 0 else null end as r from A;
哪个有效,但很烦人,因为我必须复制逻辑表达式(可能非常复杂或包含子查询等)以区分true,false和unknown – 后者应映射为null.所以我想知道T-sql专业人员是否知道更好的方法来实现这一目标?
更新:
我想指出,试图将操作数保持在整数域中的解决方案必须考虑到,一些操作数可能首先是逻辑表达式.这意味着需要一种将bool转换为值的有效解决方案.例如:
select A.x and exists (select * from B where B.y=A.y) from A;
解决方法
我不认为有一个好的答案,实际上它是Tsql的限制.
您可以为所需的每个布尔表达式创建UDF
CREATE FUNCTION AndIntInt ( @x as int,@y as int ) RETURNS int AS BEGIN if (@x<>0) and (@y<>0) return -1 if not((@x<>0) and (@y<>0)) return 0 return null END
通过使用
select AndIntInt(A.x,A.y) as r from A