我有一个带有此签名的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时,该函数可以正常工作,但是如果不为null,则查询字符串与一个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'
.......
答案 0 :(得分:1)
您可以这样解决:
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注入的危险。