Bool支持Oracle SQL

car*_*rse 8 sql oracle boolean

Oracle PL/SQL支持bool数据类型,而Oracle SQL则不支持数据类型.当您想要将PL/SQL布尔返回值处理回日常SQL时(例如下面的例子),这是众所周知的痛苦.

即使是问汤姆网站也对这种不合适感到沮丧,报告你应该将布尔列编码为固定值'Y'/'N' CHAR列,这是一个如此糟糕的副作用答案,在很多不同的层面上,我不知道从哪里开始批评它.事实上,这种响应的唯一赎回质量是(据我最近发现),许多其他数据库引擎也不支持布尔数据类型.

无论如何 - 问题......

我有一个解决以下问题的方法(虽然凌乱和冗长),所以我出于好奇而不是必要来问这个问题.但是让我感到惊讶的少数几件事之一就是聪明的程序员的聪明才智,所以希望你们中的一个人能够提出以下解决方案.

在下面的示例中,函数stock_pkg.is_in_stock()(这是我的应用程序的固有部分)返回BOOL值,导致SQL无效(请记住,SQL不支持BOOL):

SELECT part_no, stock_pkg.is_in_stock(part_no) in_stock
FROM   parts_table
Run Code Online (Sandbox Code Playgroud)

我需要的是找到一种方法来使用上面的函数调用来生成格式的有效字符串(varchar)输出:

PART_NO IN_STOCK
------- ------------
AA      YES
BB      NO
CC      NO
Run Code Online (Sandbox Code Playgroud)

(你可以用'是/否'代替'真/假','绿/红','保守/劳工'或甚至数字1/0代替所有我关心的 - 只要输出属于两个不同的一个类别.)

不幸的是,我没有权限重写原始函数以返回不同的数据类型.此外,在这个较大的应用程序中有数千个这样的函数,这使得重写它们变得不切实际.

所以在这个意义上,解决方案必须是"通用"解决方案(即不特定于此函数调用).例如,重写函数是不够的stock_pkg.is_in_stock_chr(),因为这意味着必须重新编写我的应用程序中的所有其他类似函数.

我已经尝试过了:

SELECT part_no,
       CASE WHEN stock_pkg.is_in_stock(part_no) THEN 'y' ELSE 'n' END in_stock
FROM   parts_table
Run Code Online (Sandbox Code Playgroud)

甚至我自己的包装函数:

SELECT part_no,
       my_bool_to_str(stock_pkg.is_in_stock(part_no)) in_stock
FROM   parts_table
Run Code Online (Sandbox Code Playgroud)

但是,即使在其他功能结构中包含布尔值也不会被Oracle SQL所允许(至少在Oracle 10g中不允许).

还可以选择在in_stock列内部编写子选择,但在极端示例中也可能会过于复杂,并且也可能是特定于案例的.

正如我所说,我希望在那里有一个巧妙的解决方案(或者至少是一个我碰巧忽略的非常简单的解决方案).

谢谢你的时间.

A.B*_*ade 6

您可以像这样编写自己的包装器:

CREATE OR REPLACE FUNCTION my_bool_to_str(f varchar2) RETURN VARCHAR2 IS

  b varchar2(2);

BEGIN

  EXECUTE IMMEDIATE 'declare bl boolean; begin bl := ' || f ||
                    '; if bl then :1 := ''y''; else :1 := ''n''; end if; end;'
    using out b;

  return b;

END;
Run Code Online (Sandbox Code Playgroud)

然后你可以像这样调用它:

SELECT part_no,
       my_bool_to_str('stock_pkg.is_in_stock('|| part_no|| ')') in_stock
FROM   parts_table
Run Code Online (Sandbox Code Playgroud)

与包装器的不同之处在于它将varchar作为输入而不是SQL引擎无法识别的布尔值