8

boolOracle PL/SQL 支持数据类型,而 Oracle SQL 不支持,这一直让我感到沮丧。当您想将 PL/SQL 布尔返回值处理回您的日常 SQL(下面的示例)时,这是众所周知的一大难题。

即使是 ask-Tom 网站也对这种不合适的情况感到厌烦,报告说您应该将布尔列编码为固定值'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

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

PART_NO IN_STOCK
------- ------------
AA      YES
BB      NO
CC      NO

(你可以用 'yes/no' 代替 'true/false'、'green/red'、'tory/labour' 甚至是数字 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

甚至我自己的包装函数:

SELECT part_no,
       my_bool_to_str(stock_pkg.is_in_stock(part_no)) in_stock
FROM   parts_table

但是,Oracle SQL 似乎也不允许将布尔值包装在其他功能结构中(至少在 Oracle 10g 中不允许)。

还可以选择在列内编写子选择in_stock,但这在极端示例中也可能变得过于复杂,并且还需要针对具体情况。

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

谢谢你的时间。

4

1 回答 1

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;

然后你可以这样称呼它:

SELECT part_no,
       my_bool_to_str('stock_pkg.is_in_stock('|| part_no|| ')') in_stock
FROM   parts_table

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

于 2012-11-21T11:17:54.470 回答