Return one variable from a SELECT inside a function

老子叫甜甜 提交于 2019-12-11 17:31:24

问题


I'm trying to create a function that return a varchar, one of the fields form a select, the aggregation field. I'm getting the next error:

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

What I understand is that the select produce more than one row before aggregating and this triggers the error when trying to put them 'into k, s, categories'

Here is the function:

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;

The select statement works outside the function when I run it with specific values for kind_id and system_id.

I've been trying to create a temp table so I can get the initial rows from the select and then return categories, but so far I haven't been able to find any helpful information for this particular case. Does anyone knows how can I do this, please?

Thank you.


回答1:


The problem is with your variable names:

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

You have a column called kind_id and the query will use that in preference to the PL/SQL variable of the same name.

From the documentation:

If a SQL statement references a name that belongs to both a column and either a local variable or formal parameter, then the column name takes precedence.

So you aren't matching the passed-in value, you're actually finding all rows which match system_id for any value of kind_id. (Except null, and if they have leading/trailing whitespace...)

Change your variable names so they do not clash and there is no confusion. It's common to prefix passed-in argument with, say, a p prefix so you'd be comparing with = p_kind_id, and local variables with an l prefix.

If you really want to keep the names you have, you can also prefix the references to those with the function name:

      AND STANDARDS.KIND_ID = trim(get_cat.kind_id)


来源:https://stackoverflow.com/questions/51307830/return-one-variable-from-a-select-inside-a-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!