pl / sql过程中的排序表失败

时间:2015-04-17 09:54:43

标签: sql database oracle plsql database-administration

这是pl / sql中的家庭作业。我必须对表中每行中的值进行排序,其列应从user_tab_columns中检索。 我是pl / sql的初学者。我从不同的方法尝试了很多个小时而没有正确解决它。

下面的代码可能看起来很愚蠢,但是,请你能帮助我吗?

 CREATE TABLE notat(Id Number, Col1 Number, Col2 Number, Col3 Number,   Col4 Number, Col5 Number, Col6 Number, Col7 Number);
 INSERT INTO notat VALUES(1,6,3,8,4,7,8,4);
 INSERT INTO notat VALUES(2,5,7,9,2,1,7,8);
 INSERT INTO notat VALUES(3,2,7,4,8,1,5,9);
 INSERT INTO notat VALUES(4,8,4,7,9,4,1,4);
 INSERT INTO notat VALUES(5,7,5,2,5,2,6,4);

 create or replace procedure sp1_fy_marks is
    v_colname  varchar2(10);
    v2_colname varchar2(10);
    tmp        number;
    tmp2       number;

 begin

 for row in (select * from notat)
 loop

 for x in (select column_name
            from user_tab_columns
           where table_name = 'NOTAT')
 loop

  v_colname := x.column_name;

  execute immediate 'Select ' || v_colname || ' from   NOTAT where Id='  || row.Id into tmp;

  for y in (select column_name
              from user_tab_columns
             where table_name = 'NOTAT')
  loop

    v2_colname := y.column_name;

    execute immediate 'Select ' || v2_colname || ' from NOTAT where Id=' || row.Id into tmp2;

    if tmp > tmp2 then
      execute immediate 'UPDATE NOTAT SET ' || v_colname || '=' || tmp2 || '  WHERE Id=' || row.Id;
      execute immediate 'UPDATE NOTAT SET ' || v2_colname || '=' || tmp || '  WHERE Id=' || row.Id;
    end if;

  end loop;
  end loop;
  end loop;
  end sp1_fy_marks;
  execute sp1_fy_marks;

2 个答案:

答案 0 :(得分:0)

正如我所说,这似乎是一个愚蠢的要求 - 我花了35年时间使用db并且从未想过会做那样的事情。

但是,您的代码看起来是正确的方法。不适用于PL / SQL(自从我上次使用它以来已经过了几年)我还没有检查语法或任何内容,但是如果我不得不这样做,我认为我会采用这种方法。做到这一点。

但是,如果我 必须这样做,我实际上会认为数据库设计不正确。列应包含不同类型的数据,因此无法比较。如果它们在逻辑上具有可比性,那么你有3NF的突破 - 你有一个重复的组。正确的设计会将列拆分为不同设计表中的行。然后排序是一项微不足道的练习。这就是您所提议的解决方案。

所以我说:是的,给你一个非常愚蠢的事情,在这种情况下做你最不可能的事情!

答案 1 :(得分:0)

请...,格式化代码,很容易看到和修复许多简单的问题 如果代码格式化。作为旁注,我强烈建议 你习惯于先用模式添加表名 当引用所有者架构之外的表时,所以我建议使用sys.user_tab_columns,即使技术上不必要。

create or replace procedure sp1_fy_marks is
  v_colname  varchar2(10);
  v2_colname varchar2(10);
  tmp        number;
  tmp2       number;
begin
  for row in (select * from notat)
  loop

    for x in (select column_name
                from user_tab_columns
               where table_name = 'NOTAT')
    loop

      v_colname := x.column_name;

      execute immediate 'Select ' || v_colname || ' from   NOTAT where Id=' || row.Id into tmp;

      for y in (select column_name
                  from user_tab_columns
                 where table_name = 'NOTAT')
      loop

        v2_colname := y.column_name;

        execute immediate 'Select ' || v2_colname || ' from NOTAT where Id=' || row.Id into tmp2;

        if tmp > tmp2 then
          execute immediate 'UPDATE NOTAT SET ' || v_colname || '=' || tmp2 || '  WHERE Id=' || row.Id;
          execute immediate 'UPDATE NOTAT SET ' || v2_colname || '=' || tmp || '  WHERE Id=' || row.Id;
        end if;

      end loop;
    end loop;
  end loop;
end sp1_fy_marks;
execute sp1_fy_marks;

其次,每张桌子都像一个桶,数据被倾倒在一起 在桶里没有强加的订单。选择 桶外的数据强制执行订单。这包括选择 来自sys.user_tab_columns的数据。您有两个来自sys.user_tab_columns的选择,无法保证包含列名的行完全按相同的顺序排列。

第三,您假设列的顺序,可能是订单 如果您有列a b c,那么使用select * from notat会出现这种情况 在notat中,你可以从notat'中选择b c a。或者'从notat'中选择c a b 另外,从sys.user_tab_columns中选择*,但某些强加的顺序不会 确保select * from notat

的顺序相同