pl / pgsql中的子查询不起作用

时间:2013-10-31 07:27:09

标签: postgresql plpgsql

我在postgresql中的pl / pgsql中有函数

CREATE or replace FUNCTION check_checklist_is_finalizedtest(application_id bigint)
  RETURNS SETOF record AS
$BODY$
DECLARE
sqlresult record;
val boolean:=false;

BEGIN

for sqlresult in execute IMMEDIATE 'select distinct mda.application_id maid,mda.document_type_id mdoctypeid,
dt.multiple_doc dtmdoc,mda.mandatory_doc_application_id mdocaid,COALESCE(ac.doc_correct,false) doccorrect,
COALESCE((select max(e_certificate_no) from application_document ad
 where ad.application_id=mda.application_id and ad.document_id=mda.document_type_id and multiple_doc=true and ad."valid"=''||New||''
 ),'''||1||''')as no_of_docs,
(select count(*) from application_document ad2 
 where ad2.application_id=mda.application_id and ad2.document_id=mda.document_type_id and ad2."valid"=''||New||''
 )as count_of_record     
from mandatory_doc_application mda 
inner join document_type dt on(mda.document_type_id=dt.document_id)
left  join application_checklist ac on(ac.man_doc_app_id= mda.mandatory_doc_application_id)
where mda.application_id='''||$1||''''
LOOP     
 IF(sqlresult.no_of_docs::bigint=sqlresult.count_of_record and sqlresult.doccorrect=true) then
   val=true;
 ELSE
   val=false;
 END IF;
 return next sqlresult;
END LOOP;

END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;

当调用函数时,select语句中的子查询没有被执行。结果是错误的。你能帮助我吗?

1 个答案:

答案 0 :(得分:1)

将查询转换为动态SQL可能会出错。您的问题中的代码很难阅读,这会增加出错的风险 这个奇怪的表达可能不是你认为的那样:

and ad2."valid"=''||New||''

你期望一个变量 New ,但它没有被声明,你在那里使用一个常量字符串。

下一个奇怪的事情:关键字IMMEDIATE - PostgreSQL不支持它 - 所以你的代码可能无法编译。

问题:

  • 为什么使用动态SQL?似乎没有必要这样做。
  • 如果使用动态SQL,为什么不使用像

    这样的现代表单
    FOR r IN EXECUTE 'SELECT * FROM tab WHERE somecol = $1' USING $1
    LOOP ...
    

但是使用普通的SQL,您的代码会更简单,更快捷:

BEGIN
  RETURN QUERY SELECT no_of_docs::bigint=count_of_record 
                  AND COALESCE(ac.doc_correct,false) = true
                 FROM ...;
  RETURN;
END;

请记住,只选择您实际需要返回的列 - 而不是其他列。