Postgres 函数不返回任何结果,但是当相同的查询在函数之外返回结果时

Posted

技术标签:

【中文标题】Postgres 函数不返回任何结果,但是当相同的查询在函数之外返回结果时【英文标题】:Postgres Function returning no results but when the same query returns results outside function 【发布时间】:2015-01-25 02:50:34 【问题描述】:

我正在运行一个简单的 postgres 函数来返回行数。我可以使用 raise option 的输出在函数外部运行相同的查询,但该函数不返回任何行。我尝试了不同的方法来产生结果,但不能。请在下面找到我的功能,

CREATE OR REPLACE FUNCTION my_schema.usp_spellcheck3(SearchORItems_WithPipe varchar, site varchar, lan varchar, rows_display integer)
  RETURNS TABLE (docmnt int) AS $BODY$
DECLARE
  arrSearchTerms text[];
  NewTerm varchar;
  i integer;
  AltSearch_withComma varchar;
  AltSearch_withPipe varchar;
  strDidYouMean varchar;
  dpDidYouMean double precision;
  txtDidYouMean Text;
  SearchORItems_withComma  varchar;
  SearchORItems  varchar;
  SearchORItem  varchar;
  ws varchar;
  arrSearchORItems_withComma varchar[];
BEGIN
  strDidYouMean = 'DidYouMeanRow';
  dpDidYouMean = 0.0;
  txtDidYouMean = 'DidYouMeanRow';

  ws = '''' || '%' || site || '%' || '''' ;
  RAISE NOTICE '%', ws;

  SearchORItems = REPLACE(SearchORItems_WithPipe, '|', ',');
  SELECT regexp_split_to_array(SearchORItems, ',') INTO arrSearchORItems_withComma;
  RAISE NOTICE '%', SearchORItems;

  FOR i IN 1 .. coalesce(array_upper(arrSearchORItems_withComma, 1), 1) LOOP
    IF (i = 1) THEN
      SearchORItems_withComma = '''' || arrSearchORItems_withComma[i] || '''';
    ELSE
      SearchORItems_withComma = SearchORItems_withComma||','||'''' || arrSearchORItems_withComma[i] || '''';
    END IF;
  END LOOP;
  RAISE NOTICE '%',SearchORItems_withComma;

  SELECT COUNT(*) INTO res_count 
  FROM ( 
    SELECT 1 FROM my_schema.features f , my_schema.documents d 
    WHERE term IN (SearchORItems_withComma) 
      AND d.docid = f.docid
      AND d.url LIKE ws
    GROUP BY f.docid, d.url) t; 

  RAISE NOTICE '%', res_count;

  SearchORItem = 'SELECT COUNT(*) INTO res_count
    FROM (SELECT 1 FROM my_schema.features f , my_schema.documents d 
    WHERE term IN ('||SearchORItems_withComma||') 
    AND d.docid = f.docid AND d.url LIKE ' || ws ||'
    GROUP BY f.docid, d.url) t';

  RAISE NOTICE '%',SearchORItem;
END;
$BODY$ LANGUAGE SQL VOLATILE; 

这是我的查询输出: 注意:'%uni%' 通知:丹尼尔,数据 注意:'丹尼尔','数据' 通知:0 注意:选择 count(*) 到 res_count 从(从 my_schema.features f、my_schema.documents d 中选择 1 where term in ('daniel','data') 和 d.docid=f.docid 和 d.url 像 '%uni%' 按 f.docid,d.url)t 分组

总查询运行时间:16 毫秒。 检索到 0 行。

我不知道我哪里出错了,任何帮助将不胜感激..谢谢..

【问题讨论】:

【参考方案1】:

没有返回任何内容的简单原因是您的代码中没有RETURN 语句。当函数RETURNS TABLE 时,您需要在代码主体中显式放置一个或多个RETURN NEXTRETURN QUERY 语句,最后使用RETURN 语句来指示函数的结束。请参阅此处的文档:http://www.postgresql.org/docs/9.3/static/plpgsql-control-structures.html#PLPGSQL-STATEMENTS-RETURNING。您究竟想要返回什么尚不清楚,但可能的候选人是 res_countd.docid

除此之外,您的代码可以使用真正的清理来减少混乱,例如:

ws := '''%' || site || '%''' ;

代替:

ws = '''' || '%' || site || '%' || '''' ;

和:

SELECT COUNT(*) INTO res_count 
FROM my_schema.features f,
JOIN my_schema.documents d ON d.docid = f.docid
WHERE term IN (SearchORItems_withComma) 
  AND d.url LIKE ws
GROUP BY f.docid, d.url;

代替:

SELECT COUNT(*) INTO res_count 
FROM ( 
  SELECT 1 FROM my_schema.features f , my_schema.documents d 
  WHERE term IN (SearchORItems_withComma) 
    AND d.docid = f.docid
    AND d.url LIKE ws
  GROUP BY f.docid, d.url) t;

并且您应该在任何不是 SQL 语句的 plpgsql 语句中使用赋值运算符 (:=) 而不是相等运算符。

【讨论】:

您好@Patrick,感谢您的回复.. 我会按照您的建议进行更改,但对我来说问题是结果计数 (res_count) 值为 0,而相同的查询返回一个值外部函数..我在为 IN 运算符附加引号时会出错吗?? 嗨@prasadpv。我无法给您答案,因为您尚未发布表格功能和文档的结构。让我感到奇怪的是你GROUP BY docid, url,因为这会给你多个结果(每组 1 个计数)到一个标量值 res_count。也许有一个组的命中数为 0,这个结果会返回给你。很难说。也许您可以针对这个特定问题提出一个新问题,显示表格结构。 请在下面找到文档和特征表的结构..CREATE TABLE my_schema.documents ( docid numeric NOT NULL, url 字符变化, 日期字符变化, 语言字符变化, CONSTRAINT documents_pkey PRIMARY KEY (docid) )CREATE TABLE my_schema.features ( docid 双精度 NOT NULL, 术语字符变化 NOT NULL, term_freq integer, tf numeric(10,4), doc_freq numeric(10,4), idf numeric(10,4), scores numeric(10 ,4), idf_okapi numeric(10,4), score_okapi numeric(10,4), d numeric(10,4), CONSTRAINT features_pkey PRIMARY KEY (docid, term) ) 对我来说确切的问题是 select (*) 在我执行查询时返回 1 行.. 但是当我执行它返回 0 行的函数时.. 这对我来说都很令人惊讶,因为两者是一样的..

以上是关于Postgres 函数不返回任何结果,但是当相同的查询在函数之外返回结果时的主要内容,如果未能解决你的问题,请参考以下文章

根据用户的不同,简单的select查询在postgres数据库中不返回结果。

postgres中的交叉表函数不返回表中的任何值

带有“%%”参数的 Postgres 查询未通过 psycopg2 返回结果

尽管函数定义中有 RETURN 语句,但 Postgres 查询没有结果数据的目的地

Postgresql:在不返回任何记录的视图上选择查询

这两个postgres表达式会给出相同的结果吗?