2012-04-11 2 views
0

Мне интересно, возможно ли передать (любой способ, а также хаки) условие (логическое) для пользовательской функции в Oracle.Возможно ли передать условие пользовательской функции 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

Почему бы не использовать 'BOOLEAN'? –

+0

Проверьте состояние вне вашей функции, затем передайте 1 или 0 функции? – MatBailie

+0

@PeterLang Я не могу использовать BOOLEAN в простом контексте SQL. –

ответ

3

Предполагая, что вы хотите, чтобы иметь возможность вызвать его из простой SQL - в противном случае вы могли бы просто использовать 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).

Я также рассмотрел бы, действительно ли функция необходима - в зависимости от того, что делает функция, конечно, вы, вероятно, можете добиться такого же эффекта в простом запросе, например. с заявлениями о случаях.

+0

Нет возможности использовать условие непосредственно как 'SELECT my_func (a = b)' или что-то, что не является 'SELECT my_func (CASE WHEN a = b THEN 1 ELSE 0)'? Извините, я новичок в Oracle ... * PS: что означает символ '/' после создания функции? Я также вижу его в Oracle doc, но я не могу его получить, я не использовал его во время тестов ... * –

+0

@ loernzo-s - Я добавил версию, которая показывает, что можно передать строку, подлежащую оценке как условие, но быть возможным не обязательно делает его хорошей идеей. Как предлагает Питер, пожалуйста, расширьте то, что вы действительно пытаетесь сделать, и почему вы думаете, что эта конструкция необходима. –

+0

Также ... вам нужно, чтобы '/', чтобы получить блок PL/SQL - в этом случае создание функции - должно выполняться, по крайней мере, при запуске из SQL * Plus или SQL Developer. Если у вас есть это в скрипте, и это последнее, что он будет выполнять в любом случае, но это обычно необходимо, поэтому лучше всегда использовать его, чтобы избежать путаницы. –

Смежные вопросы