我一直在研究PL / SQL脚本,它计算两个食谱之间的相似性。 Recipe 是包含所有标题,准备等的表格。 Ingredient 是存储所有独特成分的地方,配方是许多很多问题都解决了,两者有联系。
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;
/
现在,我非常确定这个功能有意义且应该工作(整个周末都带我去)。有没有人知道为什么这可能不起作用?
提前致谢。
答案 0 :(得分:1)
两个表之间没有链接:
from recipes.recipe s1, recipes.recipe s2
where s1.recipeID = idS1
and s2.recipeID = idS2;
因此,查询是交叉连接。如果recipeID
是主键,则无关紧要。但是,如果该列中有重复的数字,则查询将返回多行。如果你的查询返回多行,你的函数将抛出一个TOO_MANY_ROWS异常,因为我们只能选择一行INTO变量(除非我们使用BULK COLLECT INTO一个集合变量
。
答案 1 :(得分:0)
只应将1行返回到sim_value。要查看发生了什么,请运行不带INTO的SQL并使用IDS1和IDS2的值。