如何将true/false/unknown映射到-1/0/null而不重复?

Nor*_*ame 8 sql t-sql sql-server sql-server-2005

我目前正在开发一个工具来帮助我的用户将他们的SQL代码移植到SQL-Server 2005.为此,我将SQL解析为语法树,分析它需要注意的构造,修改它并将其转换回T - SQL.

在我想支持的事情上,其他RDBMS的"bools is values too"语义.例如,MS-Access允许我编写select A.x and A.y as r from A,这在T-SQL中是不可能的,因为:

  1. 列不能具有布尔类型(列值不能和')
  2. 在期望表达式的地方不能使用逻辑谓词.

因此,我的转换例程将上述语句转换为:

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;
Run Code Online (Sandbox Code Playgroud)

哪个有效,但很烦人,因为我必须复制逻辑表达式(可能非常复杂或包含子查询等)以区分true,false并且unknown- 后者应映射为null.所以我想知道T-SQL专业人员是否知道更好的方法来实现这一目标?

更新: 我想指出的是,该解决方案,尽量保持操作数的整数域必须考虑到,即一些操作数可以是逻辑表达式首位.这意味着需要一种将bool转换为值的有效解决方案.例如:

select A.x and exists (select * from B where B.y=A.y) from A;
Run Code Online (Sandbox Code Playgroud)

Sco*_*ein 2

我认为没有一个好的答案,这实际上是 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
Run Code Online (Sandbox Code Playgroud)

使用通过

select AndIntInt(A.x,A.y) as r from A
Run Code Online (Sandbox Code Playgroud)