【问题标题】:PL/SQL Anonymous block 'Exact fetch returns more than requested number of rows'PL/SQL 匿名块“精确提取返回的行数超过请求的行数”
【发布时间】:2013-02-12 18:09:51
【问题描述】:

我一直在编写一个 PL/SQL 脚本来计算两个食谱之间的相似度。 Recipe 是包含所有标题、准备等的表格。Ingredient 是所有独特成分的存储位置,recipeing 是许多要很多问题都解决了,两者是联系在一起的。

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;
/

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

提前致谢。

【问题讨论】:

标签: sql oracle plsql


【解决方案1】:

两个表之间没有链接:

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

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

【讨论】:

  • 我以前从未使用过交叉连接,但我是否正确地说它返回了行集的笛卡尔积?您能否详细说明如何使用它?在以前的查询中,内连接足以将表与“链接”表链接在一起 - 配方。
  • 请查看我引用的代码。这两个表(同一个表的两个实例)之间存在 NO 显式连接。这会产生一个隐式交叉连接(是的,它是一个笛卡尔积)。我不是建议你使用 CROSS JOIN,我是说你已经在这样做了,这就是导致你得到错误的原因。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-15
    • 2018-01-15
    • 1970-01-01
    • 2017-07-25
    • 1970-01-01
    相关资源
    最近更新 更多