如何使这个代码动态化

时间:2017-04-26 05:04:32

标签: oracle plsql oracle-sqldeveloper

我想让这段代码动态化,即代替n_numb number:= 1990,如果我根据你输入的那一年输入一个不同的年份它应该执行。

set SERVEROUTPUT ON

declare

  v_test varchar2(80) := 'BORN';
  n_numb number := 1990;
begin

  while v_test <> 'Birthday' 
 loop 
      if    n_numb = 1991 then v_test := 'Birthday';
      end if;
    dbms_output.put_line (v_test||': '||n_numb);
    n_numb := n_numb + 1;
  end loop;

 v_test := 'Playschool';
  while n_numb < 1994 AND v_test = 'Playschool' loop
     dbms_output.put_line (v_test||': '||n_numb);
      n_numb := n_numb + 1;
 end loop;

 v_test := 'Regularschool';
  while n_numb < 2007 AND v_test = 'Regularschool' loop
     dbms_output.put_line (v_test||': '||n_numb);
      n_numb := n_numb + 1;
 end loop;

  v_test := 'Engineering';
  while n_numb < 2011 AND v_test = 'Engineering' loop
     dbms_output.put_line (v_test||': '||n_numb);
      n_numb := n_numb + 1;
 end loop;

  v_test := 'SearchingJob';
  while n_numb < 2013 AND v_test = 'SearchingJob' loop
     dbms_output.put_line (v_test||': '||n_numb);
      n_numb := n_numb + 1;
 end loop;

  v_test := 'Working';
  while n_numb < 2014 AND v_test = 'Working' loop
     dbms_output.put_line (v_test||': '||n_numb);
      n_numb := n_numb + 1;
 end loop;
 end;

1 个答案:

答案 0 :(得分:1)

要使此代码需要一年的输入并根据已用的年份进行打印,您需要从基于年数的活动更改为年累积

我将在下面添加几个例子 第一个将修改原始代码以允许切换n_numb 第二个将重构使用procedure来简化事情。

对于第一个示例,我将从您的原始代码开始,并添加accumulator V_YEAR_ACCUMULATION来衡量年份。然后将n_numb更改为不同的值将获得不同的输出。

DECLARE
  V_TEST VARCHAR2(80) := 'BORN';
  N_NUMB NUMBER := 1990;
  V_YEAR_ACCUMULATION NUMBER := 0;
BEGIN

  WHILE V_TEST <> 'Birthday'
  LOOP
    IF V_YEAR_ACCUMULATION = 1
    THEN V_TEST := 'Birthday';
    END IF;
    DBMS_OUTPUT.put_line(V_TEST || ': ' || N_NUMB);
    N_NUMB := N_NUMB + 1;
    V_YEAR_ACCUMULATION := V_YEAR_ACCUMULATION + 1;
  END LOOP;

  V_TEST := 'Playschool';
  WHILE V_YEAR_ACCUMULATION < 4 AND V_TEST = 'Playschool' LOOP
    DBMS_OUTPUT.put_line(V_TEST || ': ' || N_NUMB);
    N_NUMB := N_NUMB + 1;
    V_YEAR_ACCUMULATION := V_YEAR_ACCUMULATION + 1;
  END LOOP;

  V_TEST := 'Regularschool';
  WHILE V_YEAR_ACCUMULATION < 17 AND V_TEST = 'Regularschool' LOOP
    DBMS_OUTPUT.put_line(V_TEST || ': ' || N_NUMB);
    N_NUMB := N_NUMB + 1;
    V_YEAR_ACCUMULATION := V_YEAR_ACCUMULATION + 1;
  END LOOP;

  V_TEST := 'Engineering';
  WHILE V_YEAR_ACCUMULATION < 21 AND V_TEST = 'Engineering' LOOP
    DBMS_OUTPUT.put_line(V_TEST || ': ' || N_NUMB);
    N_NUMB := N_NUMB + 1;
    V_YEAR_ACCUMULATION := V_YEAR_ACCUMULATION + 1;
  END LOOP;

  V_TEST := 'SearchingJob';
  WHILE V_YEAR_ACCUMULATION < 23 AND V_TEST = 'SearchingJob' LOOP
    DBMS_OUTPUT.put_line(V_TEST || ': ' || N_NUMB);
    N_NUMB := N_NUMB + 1;
    V_YEAR_ACCUMULATION := V_YEAR_ACCUMULATION + 1;
  END LOOP;

  V_TEST := 'Working';
  WHILE V_YEAR_ACCUMULATION < 24 AND V_TEST = 'Working' LOOP
    DBMS_OUTPUT.put_line(V_TEST || ': ' || N_NUMB);
    N_NUMB := N_NUMB + 1;
    V_YEAR_ACCUMULATION := V_YEAR_ACCUMULATION + 1;
  END LOOP;
END;
/

测试一下:

使用n_numb := 1990给出:

BORN: 1990
Birthday: 1991
Playschool: 1992
Playschool: 1993
Regularschool: 1994
...
...
SearchingJob: 2012
Working: 2013

但是n_numb := 1899,你得到:

BORN: 1899
Birthday: 1900
Playschool: 1901
Playschool: 1902
Regularschool: 1903

但是,有一些可以简化事情的重构 在第二个例子中,我将创建程序来进行打印,并随着年份的进行从一个活动移动到下一个活动。这将需要更少的代码。

首先,创建一个print当前activity的流程并推进years

CREATE OR REPLACE PROCEDURE GROW_OLDER(P_ACTIVITY IN VARCHAR2, P_YEARS_TO_CONTINUE IN NUMBER, P_YEARS_ACCUMULATED IN OUT NUMBER)
IS
  V_LOCAL_ACCUMULATION NUMBER := 0;
  BEGIN
    WHILE V_LOCAL_ACCUMULATION < P_YEARS_TO_CONTINUE LOOP
      DBMS_OUTPUT.put_line(UTL_LMS.FORMAT_MESSAGE('%s: %s',P_ACTIVITY,TO_CHAR(P_YEARS_ACCUMULATED + V_LOCAL_ACCUMULATION)));
      V_LOCAL_ACCUMULATION := V_LOCAL_ACCUMULATION + 1;
      END LOOP;
    P_YEARS_ACCUMULATED := P_YEARS_ACCUMULATED + P_YEARS_TO_CONTINUE;
  END;
/

然后创建一个程序来协调多年来从活动到活动的运动:

CREATE OR REPLACE PROCEDURE MOVE_THROUGH_THE_YEARS(P_START_YEAR IN NUMBER)
IS
  V_YEAR_ACCUMULATION NUMBER := P_START_YEAR;
  BEGIN
    GROW_OLDER('Born', 1, V_YEAR_ACCUMULATION);
    GROW_OLDER('Birthday', 1, V_YEAR_ACCUMULATION);
    GROW_OLDER('Playschool', 2, V_YEAR_ACCUMULATION);
    GROW_OLDER('Regularschool', 13, V_YEAR_ACCUMULATION);
    GROW_OLDER('Engineering', 4, V_YEAR_ACCUMULATION);
    GROW_OLDER('SearchingJob', 2, V_YEAR_ACCUMULATION);
    GROW_OLDER('Working', 1, V_YEAR_ACCUMULATION);
  END;
/

然后测试一下。从1990开始:

BEGIN
  MOVE_THROUGH_THE_YEARS(1990);
END;
/

Born: 1990
Birthday: 1991
Playschool: 1992
Playschool: 1993
Regularschool: 1994
Regularschool: 1995
...
...
Engineering: 2010
SearchingJob: 2011
SearchingJob: 2012
Working: 2013

2077

BEGIN
  MOVE_THROUGH_THE_YEARS(2077);
END;
/

Born: 2077
Birthday: 2078
Playschool: 2079
Playschool: 2080
Regularschool: 2081
Regularschool: 2082
...
...
Engineering: 2097
SearchingJob: 2098
SearchingJob: 2099
Working: 2100

编辑如果您只想打印一次活动,可以将上面的GROW_OLDER程序替换为不循环的替代程序。

CREATE OR REPLACE PROCEDURE GROW_OLDER(P_ACTIVITY IN VARCHAR2, P_YEARS_TO_CONTINUE IN NUMBER, P_YEARS_ACCUMULATED IN OUT NUMBER)
IS
  BEGIN
    DBMS_OUTPUT.put_line(UTL_LMS.FORMAT_MESSAGE('%s: %s',P_ACTIVITY,TO_CHAR(P_YEARS_ACCUMULATED)));
    P_YEARS_ACCUMULATED := P_YEARS_ACCUMULATED + P_YEARS_TO_CONTINUE;
  END;
/

CREATE OR REPLACE PROCEDURE MOVE_THROUGH_THE_YEARS(P_START_YEAR IN NUMBER)
IS
  V_YEAR_ACCUMULATION NUMBER := P_START_YEAR;
  BEGIN
    GROW_OLDER('Born', 1, V_YEAR_ACCUMULATION);
    GROW_OLDER('Birthday', 1, V_YEAR_ACCUMULATION);
    GROW_OLDER('Playschool', 2, V_YEAR_ACCUMULATION);
    GROW_OLDER('Regularschool', 13, V_YEAR_ACCUMULATION);
    GROW_OLDER('Engineering', 4, V_YEAR_ACCUMULATION);
    GROW_OLDER('SearchingJob', 2, V_YEAR_ACCUMULATION);
    GROW_OLDER('Working', 1, V_YEAR_ACCUMULATION);
  END;
/

然后测试一下:

BEGIN
  MOVE_THROUGH_THE_YEARS(1990);
END;
  /

结果:

Born: 1990
Birthday: 1991
Playschool: 1992
Regularschool: 1994
Engineering: 2007
SearchingJob: 2011
Working: 2013

修改如果您需要一个每个活动一行的匿名阻止,请举例说明:

DECLARE
  V_YEARS NUMBER := 1990;
  BEGIN
  DBMS_OUTPUT.put_line(UTL_LMS.FORMAT_MESSAGE('Born: '||TO_CHAR(V_YEARS)));
  V_YEARS := V_YEARS + 1;
  DBMS_OUTPUT.put_line(UTL_LMS.FORMAT_MESSAGE('Birthday: '||TO_CHAR(V_YEARS)));
  V_YEARS := V_YEARS + 1;
  DBMS_OUTPUT.put_line(UTL_LMS.FORMAT_MESSAGE('Playschool: '||TO_CHAR(V_YEARS)));
  V_YEARS := V_YEARS + 2;
  DBMS_OUTPUT.put_line(UTL_LMS.FORMAT_MESSAGE('Regularschool: '||TO_CHAR(V_YEARS)));
  V_YEARS := V_YEARS + 13;
  DBMS_OUTPUT.put_line(UTL_LMS.FORMAT_MESSAGE('Engineering: '||TO_CHAR(V_YEARS)));
  V_YEARS := V_YEARS + 4;
  DBMS_OUTPUT.put_line(UTL_LMS.FORMAT_MESSAGE('SearchingJob: '||TO_CHAR(V_YEARS)));
  V_YEARS := V_YEARS + 2;
  DBMS_OUTPUT.put_line(UTL_LMS.FORMAT_MESSAGE('Working: '||TO_CHAR(V_YEARS)));
  V_YEARS := V_YEARS + 1;
END;
/

输出与所有其他示例相同:

Born: 1990
Birthday: 1991
Playschool: 1992
Regularschool: 1994
Engineering: 2007
SearchingJob: 2011
Working: 2013