Составьте строковый запрос в функции postgresql с аргументом NULL - PullRequest
0 голосов
/ 06 сентября 2018

У меня есть функция postgresql с этой подписью:

ver_hijos(
    IN cod character varying,
    IN idpadre integer,
    IN idhijo integer)

В теле функции у меня есть следующее:

     FOR var_r IN EXECUTE 'SELECT ' || 
    ...........
    ' FROM '||....
     ' WHERE '||....
     ' AND 
        CASE WHEN ' || idpadre || ' IS NULL 
        THEN '||tabla_relacion||'.id_padre IS NULL 
        ELSE '||tabla_relacion||'.id_padre = '||idpadre||'
        END
        AND '||tabla_relacion||'.id_hijo = '||tabla_conceptos||'.id'            

Функция работает нормально, когда idpadre нетnull, но если нет, строка запроса объединяется с пустой строкой, и она становится недействительной, получая следующую ошибку:

ERROR:  query string argument of EXECUTE is null
CONTEXT:  PL/pgSQL function ver_hijos(character varying,integer,integer) line 10 at FOR over EXECUTE statement

********** Error **********

ERROR: query string argument of EXECUTE is null
SQL state: 22004
Context: PL/pgSQL function ver_hijos(character varying,integer,integer) line 10 at FOR over EXECUTE statement

¿Как правильно построить функцию для принятия значений NULL и не повредитьстрока?

Редактировать:

Если я использую format () для построения запроса:

     FOR var_r IN EXECUTE format('SELECT ' || 
            ...........
            ' FROM '||....
             ' WHERE '||....
             ' AND 
                CASE WHEN ' || idpadre || ' IS NULL 
                THEN '||tabla_relacion||'.id_padre IS NULL 
                ELSE '||tabla_relacion||'.id_padre = '||idpadre||'
                END
                AND '||tabla_relacion||'.id_hijo = |tabla_conceptos||'.id'
                ,idpadre,idpadre)

и я использую нулевой аргумент idpadre=null, я получаю эту ошибку:

ERROR:  null values cannot be formatted as an SQL identifier
CONTEXT:  PL/pgSQL function ver_hijos(character varying,integer,integer) line 10 at FOR over EXECUTE statement
********** Error **********

ERROR: null values cannot be formatted as an SQL identifier
SQL state: 22004
Context: PL/pgSQL function ver_hijos(character varying,integer,integer) line 10 at FOR over EXECUTE statement

Это мой обходной путь для его решения:

DECLARE
........
str_null_case character varying;
........
BEGIN
........
IF idpadre IS NULL THEN
    str_null_case := tabla_relacion||'.id_padre IS NULL';
ELSE
    str_null_case := tabla_relacion||'.id_padre = '||idpadre;
END IF;
........
BODY
.......
' WHERE '||tabla_conceptos||'.id ='|| idhijo ||
 ' AND '||str_null_case||    
 ' AND '||tabla_relacion||'.id_hijo = '||tabla_conceptos||'.id' 
.......

1 Ответ

0 голосов
/ 06 сентября 2018

Вы можете решить это так:

EXECUTE '... CASE WHEN ' || (idpadre IS NULL) || ' THEN ...';

Для ветви ELSE вы можете использовать coalesce(idpadre, '').

Но было бы намного лучше написать все как

EXECUTE format('... WHERE %I.id_padre IS NOT DISTINCT FROM $1',
               tabla_relacion)
USING idpadre;

Это проще и позволяет избежать опасности внедрения SQL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...