Это может быть намного проще, безопаснее и быстрее (при условии, по крайней мере, Postgres 8.4):
CREATE OR REPLACE FUNCTION foo(_corp_coun_id int) -- guessing type
RETURNS TABLE (
emp_no int -- guessing data types ..
,dept_name text -- .. replace with actual types
,sub_dept_id int
,sub_dept_name text
,desig_name text
,empname text) AS
$func$
BEGIN
RETURN QUERY
SELECT em.emp_no
,dp.dept_name
,sb.sub_dept_id
,sb.sub_dept_name
,ds.desig_name
,concat_ws(' ', em.first_name, em.middle_name, em.surname) -- AS empname
FROM adm_m_department dp
JOIN adm_m_subdepartment su ON sb.dept_id = dp.dept_id
JOIN est_emp_empmaster em ON em.dept_id = sb.dept_id
AND em.sub_dept_id = sb.sub_dept_id
JOIN est_emp_salary sl ON sl.emp_no = em.emp_no
AND sl.retired_flag = 'N' -- untangled join cond.
JOIN est_m_designation ds ON ds.desig_code = sl.pre_desig_code
WHERE em.corp_coun_id = 0 OR
em.corp_coun_id IS NULL OR
em.corp_coun_id = $1
ORDER BY dp.dept_id, sb.sub_dept_id, em.emp_no;
END
$func$
LANGUAGE plpgsql SET search_path=public;
Чтобы ответить на ваш основной вопрос : используйте concat_ws()
для простой и безопасной конкатенации нескольких столбцов (не сбой при NULL
).
Здесь вам не нужен динамический SQL, поскольку переменные являются только значениями (не идентификаторами).
Вам не нужно CURSOR
здесь.
Вам не нужно LOOP
.RETURN QUERY
делает то же самое, проще и быстрее.
Вам не нужны псевдонимы столбцов, только имена параметров OUT
(неявно имена столбцов в RETURNS TABLE (...)
)релевантный.
Замените квалификацию множественной схемы public.
в вашем запросе одним SET search_path = public
.
Я также распутал ваш запрос,использовали псевдонимы коротких таблиц и переформатировали, чтобы было легче читать.
Вам даже не нужен plpgsql здесь.Может быть проще функция SQL :
CREATE OR REPLACE FUNCTION foo(_corp_coun_id int)
RETURNS TABLE (
emp_no int -- guessing data types ..
,dept_name text -- .. replace with actual types!
,sub_dept_id int
,sub_dept_name text
,desig_name text
,empname text) AS
$func$
SELECT em.emp_no
,dp.dept_name
,sb.sub_dept_id
,sb.sub_dept_name
,ds.desig_name
,concat_ws(' ', em.first_name, em.middle_name, em.surname) -- AS empname
FROM adm_m_department dp
JOIN adm_m_subdepartment sb ON sb.dept_id = dp.dept_id
JOIN est_emp_empmaster em ON em.dept_id = sb.dept_id
AND em.sub_dept_id = sb.sub_dept_id
JOIN est_emp_salary sl ON sl.emp_no = em.emp_no
AND sl.retired_flag = 'N' -- untangled join cond.
JOIN est_m_designation ds ON ds.desig_code = sl.pre_desig_code
WHERE em.corp_coun_id = 0 OR
em.corp_coun_id IS NULL OR
em.corp_coun_id = $1
ORDER BY dp.dept_id, sb.sub_dept_id, em.emp_no;
$func$
LANGUAGE sql SET search_path=public;