是否可以将条件传递给Oracle用户定义的函数?

时间:2012-04-11 10:46:23

标签: sql oracle user-defined-functions

我想知道是否可以将条件(布尔值)传递给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;

1 个答案:

答案 0 :(得分:3)

假设您希望能够从纯SQL中调用它 - 否则您可以使用BOOLEAN - 您可以传递固定值并对其进行解释。 0/1,Y / N等是常见的;使用1作为true(以及其他任何为false),例如:

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)这样的东西。

我还要考虑一个函数是否真的有必要 - 当然,根据函数的作用,你可以在一个简单的查询中实现相同的效果,例如:用案例陈述。