【问题标题】:execute immediate statement in nested loop does not work PL/SQL在嵌套循环中执行立即语句不起作用 PL/SQL
【发布时间】:2014-04-25 01:10:55
【问题描述】:
create or replace procedure NN(k number) as

cursor cursor1 IS 
select id,x,y from query_points;

cursor cursor2 IS
select x,y from data_points;

sid number;

x1 number;
y1 number;

x2 number;
y2 number;

dist number;
result number;

begin
open cursor1;

loop
    execute immediate 'delete from temp';
    fetch cursor1 into sid, x1, y1;

    exit when cursor1%notfound;


    for rec in (select x,y from data_points) loop
        x2 := rec.x;
        y2 := rec.y;

        dist:= sqrt(((x2-x1)**2)+((y2-y1)**2)); 

        execute immediate 'insert into temp values('||dist||')';    
    end loop;
    select distance into result from temp where rownum=k order by distance;
    execute immediate 'insert into nn_results values('||sid||','||k||','||result||')';
end loop;

close cursor1;
end;

此过程中的动态sql语句在循环中不执行,而是单独执行。

此外,该过程不会终止。它会导致 google chrome 崩溃。

有经验的吗?

【问题讨论】:

    标签: sql dynamic plsql


    【解决方案1】:

    EXECUTE IMMEDIATE 在这种情况下不是必需的。试试看:

    create or replace procedure NN(k number) as
      dist number;
      result number;
    begin
      for aRow IN (select id,x,y from query_points)
      loop
        delete from temp;
    
        for rec in (select x,y from data_points)
        loop
          dist:= sqrt(((rec.X-aRow.X)**2)+((rec.Y-aRow.Y)**2)); 
    
          insert into temp values(dist);
        end loop;
    
        SELECT DISTANCE
          into result
          FROM (select distance, ROWNUM as RNUM
                  from temp
                  order by distance)
          where rnum = k;
    
        insert into nn_results values(aRow.ID, k, result);
      end loop;
    end NN;
    

    使用游标 FOR 循环和行变量大大简化了代码。

    分享和享受。

    【讨论】:

    • 谢谢。但这个过程似乎也没有终止。
    • 我怀疑其中存在一些我无法诊断的逻辑问题,因为我不了解您要完成的工作,也看不到您正在使用的数据。我注意到的一件事是,驱动循环的查询都没有 WHERE 子句,因此它们正在读取这些表中的每一行,这可能是问题的一部分。您可能想要创建一个SQLFiddle,以便人们可以弄乱您的数据 - 它可能会帮助您弄清楚发生了什么。祝你好运。
    • 是的,我们打算阅读表格的每个部分。我正在尝试获取空间点的第 K 个最近邻居。因此,我正在计算每个点(在 query_points 中)与其他点(data_points)的距离,并将这些结果临时存储在表中(temp)。然后我将临时表中的第 k 个值按距离排序为第 k 个最近邻。
    • 啊 - 我想我现在看到了问题所在。这里的问题是,在查询实际返回结果之前,不会分配 ROWNUM;因此,如果您说“SELECT * FROM TEMP WHERE ROWNUM = 92”之类的话,您将永远不会得到结果,因为要达到 ROWNUM=92,您首先必须选择 ROWNUM=1 到 91 的行。我已经修改了 @987654324 @query 在上面的代码中解决这个问题。分享和享受。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多