从函数内部的SELECT返回一个变量

时间:2018-07-12 14:10:07

标签: oracle plsql oracle11g

我正在尝试创建一个返回varchar的函数,该字段之一构成select的聚合字段。我遇到下一个错误:

ORA-01422: exact fetch returns more than requested number of rows 

我了解的是,选择在聚合之前会产生多行,并且在尝试将它们“放入k,s,类别”时会触发错误

功能如下:

FUNCTION get_cat(kind_id IN varchar, system_id IN Number) RETURN VARCHAR2 
   AS categories VARCHAR2(2000);
   k STANDARDS.KIND_ID%TYPE;
   s SEEDTEST_RESULT.SLRN_ID%TYPE;   
BEGIN 

  SELECT STANDARDS.KIND_ID, SEEDTEST_RESULT.SLRN_ID, 
         listagg(CAT_LEVEL, ' ' ) within group (order by cat_level)
  INTO k, s, categories
  FROM STANDARDS, SEEDTEST_RESULT
  WHERE STANDARDS.CL_PRIORITY = SEEDTEST_RESULT.CL_PRIORITY
      AND SEEDTEST_RESULT.RESULT = 1
      AND SEEDTEST_RESULT.TEST_TYPE = 'C'
      AND STANDARDS.KIND_ID = trim(kind_id)
      AND SEEDTEST_RESULT.SLRN_ID = system_id
  GROUP BY STANDARDS.KIND_ID, SEEDTEST_RESULT.SLRN_ID;

  RETURN categories; 

END get_cat;

当我使用kind_id和system_id的特定值运行select语句时,它会在函数之外运行。

我一直试图创建一个临时表,以便可以从select中获取初始行,然后返回类别,但是到目前为止,我还无法找到针对此特定情况的任何有用信息。有人知道我该怎么做吗?

谢谢。

1 个答案:

答案 0 :(得分:2)

问题出在您的变量名上:

FUNCTION get_cat(kind_id IN varchar, ...
...
      AND STANDARDS.KIND_ID = trim(kind_id)

您有一个名为kind_id的列,查询将优先使用该列,而不使用相同名称的PL / SQL变量。

From the documentation

  

如果SQL语句引用的名称既属于列又属于局部变量或形式参数,则该列名称优先。

因此,您与传入的值不匹配,实际上您发现的是system_id any 值与kind_id匹配的所有行。 (除了null,如果它们有前导/尾随空格...)

更改变量名,以免它们冲突且不会引起混淆。通常用p前缀为传入的参数添加前缀,这样您就可以与= p_kind_id和带有l前缀的局部变量进行比较。

如果您确实想保留自己的名称,则还可以在函数名称前加上引用:

      AND STANDARDS.KIND_ID = trim(get_cat.kind_id)