3

我一直在研究计算两个配方之间相似度的 PL/SQL 脚本。 配方是包含所有标题、准备等的表格。成分是存储所有独特成分的地方,而配方是解决多对多问题的地方,两者是联系在一起的。

CREATE OR REPLACE FUNCTION func_similarity
  (idS1 IN recipes.recipe.recipeID%type , idS2 IN recipes.recipe.recipeID%type ) 
  RETURN NUMBER 
AS 
sim_value NUMBER := 0;
BEGIN
SELECT  2* 
    (select count(*) from recipes.ingredient i where i.ingredientID in (
      Select distinct ingredientID from recipes.recipeing where recipeID = s1.recipeID
      intersect
      select distinct ingredientID from recipes.recipeing  where recipeID = s2.recipeID))  
     /      ((select distinct count(ingredientID) from RECIPES.recipeing where recipeID = s1.recipeID) +
         (select distinct count(ingredientID) from recipes.recipeing where recipeID = s2.recipeID) )   INTO sim_value
from recipes.recipe s1, recipes.recipe s2
where s1.recipeID = idS1
and s2.recipeID = idS2;

RETURN (sim_value);
END func_similarity;
/

但是,当我使用匿名块对其进行测试时,出现错误: “精确提取返回的行数超过了请求的行数”

declare
v_sim number;
begin
v_sim:=func_similarity(1,4);
dbms_output.put_line(v_sim);
end;
/

现在,我很确定这个功能是有意义的并且应该可以工作(花了我整个周末)。有没有人知道为什么这可能不起作用?

提前致谢。

4

2 回答 2

1

两个表之间没有链接:

from recipes.recipe s1, recipes.recipe s2
where s1.recipeID = idS1
and s2.recipeID = idS2;

因此,查询是交叉连接。recipeID如果是主键,这无关紧要。但是,如果您在该列中有重复的数字,您的查询将返回不止一行。如果您的查询返回多行,您的函数将抛出一个 TOO_MANY_ROWS 异常,因为我们只能选择一行 INTO 变量(除非我们使用 BULK COLLECT INTO 集合变量。

于 2013-02-12T10:09:51.190 回答
0

只有 1 行应返回到 sim_value。要查看发生了什么,请在没有 INTO 的情况下运行 SQL,并使用 IDS1 和 IDS2 的值。

于 2013-02-12T10:01:23.293 回答