1

我想知道是否可以将条件(布尔值)传递(任何方式都可以,也可以破解)Oracle 中的用户定义函数。

假设我想要类似的东西:

CREATE OR REPLACE FUNCTION SCHEMA.MY_FUNC (
    condition IN ???,
    my_value IN NUMBER) RETURN NUMBER IS
BEGIN
    IF condition THEN
        RETURN my_value + 1;
    END IF;
    RETURN my_value;
END;
4

1 回答 1

3

假设您希望能够从普通 SQL 调用它 - 否则您可以只使用 a BOOLEAN- 您可以传递一个固定值并改为解释它。0/1、Y/N等常见;使用 1 作为真(和其他任何东西作为假),例如:

CREATE OR REPLACE FUNCTION MY_FUNC (
    condition IN NUMBER,
    my_value IN NUMBER) RETURN NUMBER IS
BEGIN
    IF condition = 1 THEN
        RETURN my_value + 1;
    END IF;
    RETURN my_value;
END;
/

FUNCTION MY_FUNC compiled

select my_func(0, 42) from dual;
select my_func(1, 42) from dual;

MY_FUNC(0,42)
-------------
           42 

MY_FUNC(1,42)
-------------
           43 

如果你可以将表达式作为字符串传递,比如说,你可以用动态 SQL 来破解一些东西,我想:

CREATE OR REPLACE FUNCTION my_func (
    condition IN varchar2,
    my_value IN NUMBER) RETURN NUMBER IS
    boolstr VARCHAR2(5);
BEGIN
    EXECUTE IMMEDIATE 'SELECT CASE WHEN ' || condition
        || ' THEN ''true'' ELSE ''false'' END FROM dual' INTO boolstr;
    IF boolstr = 'true' THEN
        RETURN my_value + 1;
    END IF;
    RETURN my_value;
END;
/

你必须这样称呼:

select my_func('1=1', 42) from dual;

所以你必须将你的条件构建成一个字符串,比如:

select my_func(a ||'='|| b, 42) from <some table with a and b columns>;

这看起来相当笨拙,并且允许几乎任何东西作为条件传递,这当然可能是危险的(SQL 注入可能性,委婉地说)。如果只有某些“条件”,最好使用带有简单参数的函数包装器并找出布尔条件值来调用真正的函数,这样你就可以调用类似my_func_eq(42, a, b).

我还会考虑一个函数是否真的有必要——当然,这取决于函数在做什么,您可能可以在一个简单的查询中达到相同的效果,例如使用 case 语句。

于 2012-04-11T11:13:15.947 回答