2012-01-17 1 views
1

Этот вопрос есть о Postgresql 8.3.if-statement с строкой, содержащей условие

У меня есть таблица с полем, содержащим такие условия, как «lastcontact is null». В коде, я хочу перебрать эту таблицу и для каждой записи, я хочу, чтобы проверить «если условие то», как в этом примере:

FOR myrec IN 
    SELECT * FROM tabel ORDER BY colorlevel, volgnummer 
LOOP 
    if (myrec.conditie) then 
     raise notice 'Condition % is true', myrec.conditie; 
    else 
     raise notice 'Condition % is false', myrec.conditie; 
    end if; 
END LOOP; 

таблица, которую я назвал «Tabel» в этом примере:

ID | Conditie    | Colorlevel | Volgnummer | Code | Description 
1 | lastcontact is null | 1   | 1   | ... | ... 
2 | lastchanged is null | 1   | 2   | ... | ... 
3 | lastmodified is null | 1   | 3   | ... | ... 

Возможно ли выполнить проверку, которую я хочу? Код выше, приводит следующее сообщение об ошибке:

ERROR: invalid input syntax for type boolean: "lastcontact is null" 

Новый раздел, содержащий результат функции Эрвина

Я использовал эту функцию:

CREATE OR REPLACE FUNCTION foo(lastcontact timestamptz) 
    RETURNS void AS 
$BODY$ 
DECLARE 
    myrec record; 
    mycond boolean; 
BEGIN 

FOR myrec IN 
    SELECT * FROM tabel ORDER BY colorlevel, volgnummer 
LOOP 
    EXECUTE 'SELECT ' || myrec.conditie || ' FROM tabel' INTO mycond; 

    IF mycond then 
     RAISE NOTICE 'Condition % is true', myrec.conditie; 
    ELSE 
     RAISE NOTICE 'Condition % is false', COALESCE(myrec.conditie, 'NULL'); 
    END IF; 
END LOOP; 

END; 
$BODY$ 
language 'plpgsql' volatile 
cost 100; 

Я получаю эта ошибка:

ERROR: column "lastcontact" does not exist 
LINE 1: SELECT lastcontact is null FROM tabel 
     ^
QUERY: SELECT lastcontact is null FROM tabel 
CONTEXT: PL/pgSQL function "foo" line 9 at EXECUTE statement1 

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

ответ

1

Из комментариев я, наконец, думаю, что понимаю. Вам нужно dynamic SQL:

CREATE OR REPLACE FUNCTION foo(lastcontact timestamptz) 
    RETURNS void AS 
$func$ 
DECLARE 
    myrec record; 
    mycond boolean; 
BEGIN 

FOR myrec IN 
    SELECT * FROM tabel ORDER BY colorlevel, volgnummer 
LOOP 
    IF myrec.conditie ~~ '%lastcontact %' THEN -- special case for input param 
     myrec.conditie := replace (myrec.conditie 
         , 'lastcontact ' 
         , CASE WHEN lastcontact IS NULL THEN 'NULL ' 
          ELSE '''' || lastcontact::text || ''' ' END); 
    END IF; 

    EXECUTE 'SELECT ' || myrec.conditie || ' FROM tabel' INTO mycond; 

    IF mycond then 
     RAISE NOTICE 'Condition % is true', myrec.conditie; 
    ELSE 
     RAISE NOTICE 'Condition % is false', COALESCE(myrec.conditie, 'NULL'); 
    END IF; 
END LOOP; 

END 
$func$ LANGUAGE plpgsql; 

Имейте в виду, однако, что эта установка широко открыта для инъекций SQL. Используйте только проверенный ввод. Функция работает в PostgreSQL 8.3 также (нет DO заявлений, пока).

Вы не можете ссылаться на параметры внутри динамического SQL (EXECUTE). Вы должны поместить значение в строку запроса.

В PostgreSQL 8.4 или более поздней версии у вас есть товар высшего качества USING clause. Увы, не в версии 8.3. Вы должны рассмотреть возможность обновления, если сможете.

Я применил обходное решение для вашей старой версии. Вы должны обратить особое внимание на значение NULL.

+0

Это не определение таблицы, но оно показывает три строки примера. Что, если поле «conditie» будет содержать «lastcontact Leonard

+0

Поле имеет тип 'boolean', как сообщает нам сообщение об ошибке. Поэтому он может содержать 'NULL',' TRUE' или 'FALSE'. Ничего другого, особенно не строка ''lastcontact

+0

столбец является строкой. Я получаю строку, и она должна дать мне TRUE 'FALSE'. Строка содержит условие. Если я скажу «если lastcontact Leonard

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

  • Нет связанных вопросов^_^