小编典典

布尔支持Oracle SQL

sql

我一直感到沮丧的是,Oracle PL / SQL支持bool数据类型,而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

(您可以将“是/否”替换为“真/假”,“绿色/红色”,“玩具/劳动”,甚至用数字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列内编写子选择,但是在极端示例中,这也可能会变得过于复杂,并且会因具体情况而异。

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

谢谢你的时间。


阅读 179

收藏
2021-03-10

共1个答案

小编典典

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

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引擎无法识别的布尔值

2021-03-10