-3

我在 postgresql 的 pl/pgsql 中有函数

IE

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语句中的子查询没有被执行。因此结果是错误的。你能帮帮我吗?

4

1 回答 1

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;

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

于 2013-10-31T08:21:18.080 回答